Why Next.js Caching Confuses Everyone
Caching is the single most misunderstood part of the App Router. The confusion is not because it is badly designed — it is because there are several different caches working at different layers, and most tutorials lump them together. Once you can name the four caches and what each one does, the mystery disappears.
The Four Caches
1. Request Memoization
Within a single render, if you call the same fetch twice, Next.js only runs it once. This is automatic, short-lived, and exists so you can fetch the same data in a layout and a page without doubling the work. You rarely have to think about it.
2. The Data Cache
This persists fetched data across requests and even across deploys. It is what lets your app serve data without hitting your database on every visit. You control it per-fetch with options that say "cache this," "never cache this," or "revalidate this every N seconds."
3. The Full Route Cache
At build time, Next.js can render a route to static HTML and cache it. Visitors get that pre-rendered HTML instantly. A route stays in this cache as long as its data is considered fresh and it has no dynamic, per-request behaviour.
4. The Router Cache
This lives in the browser. As users navigate, Next.js caches visited routes client-side so going back is instant. It is the one that occasionally surprises people with "why am I seeing old data after navigating back?"
Controlling Freshness
You have two main levers for keeping data fresh:
- Time-based revalidation — tell a route or fetch to refresh every N seconds. Good for data that changes predictably, like a product list.
- On-demand revalidation — explicitly clear the cache for a path or tag when something changes, such as after a user publishes a post. This gives you instant freshness without short revalidation windows hammering your backend.
The Mental Model That Fixes It
Ask two questions for any piece of data: how fresh does this need to be? and what event makes it stale? Truly static content (a marketing page) can cache aggressively. User-specific data (a dashboard) should usually opt out of caching. Content that changes on a known action (a blog post) is the perfect case for on-demand revalidation. Almost every caching decision falls cleanly into one of those three buckets.
Common Mistakes
- Caching user-specific data — and serving one user's data to another. Opt dynamic, personalized routes out of caching.
- Forgetting the router cache — stale data after client navigation is usually this, not the server.
- Over-short revalidation — a one-second window is barely caching at all and just adds load.
How Dharmsy Gets Caching Right
We map every data source in an app to one of the three freshness buckets before writing caching code, which removes the guesswork. If your Next.js app is serving stale data or hammering your database, a caching audit usually fixes both at once.

