Demystify Next.js caching layers — the Data Cache, Full Route Cache, Router Cache, and ISR — with practical examples for each.

Abdur Razzak
Full-Stack Web Developer
Next.js caching is a multi-layered system designed to maximize performance at every level. Understanding it is essential for building fast, correct applications. There are four main caching mechanisms: the Request Memoization (per-render deduplication), the Data Cache (persistent fetch cache), the Full Route Cache (rendered HTML and RSC payload), and the Router Cache (client-side navigation cache).
The Data Cache persists fetch() results across requests and deployments. It is stored on the Next.js server and survives server restarts on Vercel. By default in Next.js 15, fetch requests are NOT cached (no-store). Opt in with { next: { revalidate: 3600 } } for time-based revalidation or { cache: 'force-cache' } for permanent caching. Revalidate the cache on demand with revalidatePath() or revalidateTag() in Server Actions.
ISR lets you update static pages after deployment without rebuilding the whole site. Set revalidate in your page's fetch calls or export a revalidate constant from your page file. When a request comes in after the revalidation period, Next.js serves the stale page immediately while regenerating it in the background. The next visitor gets the fresh page. This is the stale-while-revalidate pattern at the page level.
The Full Route Cache stores the rendered HTML and RSC (React Server Component) payload for static routes on the server. Routes with no dynamic data are fully cached at build time. Dynamic routes (using cookies, headers, or no-store fetches) opt out of the Full Route Cache and render on every request. Partial prerendering (PPR), an experimental Next.js feature, lets static and dynamic content coexist on the same page.
The Router Cache lives in the browser and stores RSC payloads for routes the user has visited or prefetched. It enables instant navigation between already-visited pages and makes the browser back button feel instant. The cache has a short TTL — 30 seconds for dynamic pages and 5 minutes for static pages. You can invalidate it with router.refresh() or by calling a Server Action that uses revalidatePath.
The most common caching mistake is serving stale data to users after mutations. Always call revalidatePath or revalidateTag in your Server Actions after database writes. Another common issue is accidentally caching sensitive user data — ensure any page that reads cookies or session data is dynamic (it opts out of the Full Route Cache automatically). Use the Next.js DevTools or console.log on the server to confirm whether a route is static or dynamic.