Caching in the Next.js App Router confuses almost everyone — "why is my data stale?" is the most-asked question in any Next.js channel. The fix isn’t to fight the cache; it’s to understand the four caches and the handful of knobs that control them. Once it clicks, App Router caching becomes one of Next.js’ best features.
The four caches
- Request Memoization — dedupes identical
fetch()calls within a single render pass. - Data Cache — persists fetch results across requests and deploys until you revalidate.
- Full Route Cache — caches the rendered HTML/RSC payload of static routes at build time.
- Router Cache — client-side cache of visited routes for instant back/forward navigation.
The Data Cache and revalidation
This is the one you’ll touch most. By default fetches are cached; control freshness with revalidate, or invalidate on demand with revalidateTag / revalidatePath.
// Time-based: refresh at most every 60s (ISR)
const posts = await fetch(api, { next: { revalidate: 60 } });
// Tag-based: cache until you invalidate the tag
const post = await fetch(url, { next: { tags: ['post'] } });
// Always fresh (opt out of the Data Cache)
const live = await fetch(url, { cache: 'no-store' });'use server';
import { revalidateTag } from 'next/cache';
export async function updatePost() {
// ...write to your CMS/db...
revalidateTag('post'); // bust just the tagged data
}Static vs dynamic rendering
A route is static unless something forces it dynamic — reading cookies(), headers(), or searchParams, or using cache: "no-store". You can also be explicit:
export const dynamic = 'force-dynamic'; // never statically cache
// or
export const revalidate = 30; // ISR for the whole routeThe gotchas that bite people
- Stale data after a write → you forgot to
revalidateTag/revalidatePath. - "It works locally but not in prod" → dev disables some caching; always test a production build.
- Personalized data leaking → don’t statically cache routes that read cookies/headers.
A mental model
Ask two questions per route: "How fresh must this be?" (static → ISR → dynamic) and "What invalidates it?" (time vs an event). Answer those and the four caches stop being magic.
Related: Make your Next.js site rank (technical SEO) · Build a RAG chatbot with Next.js
Don’t disable the cache because it confused you once. Learn the two knobs — revalidate and tags — and let Next.js make your site fast by default.