Next.js App Router Caching โ Cheat Sheet
Next.js caches at multiple layers. This guide compresses the official caching docs into a quick reference.
1. The Cache Layers
- React Request Memoization
- Deduplicates repeated
fetch
calls during a single render. - Cleared after render; not persistent across requests.
- Deduplicates repeated
- Data Cache (server, persistent)
- Stores
fetch
results across requests. - Controlled by
cache
andnext.revalidate
. force-cache
โ uses it.no-store
โ skips it.next.revalidate
โ ISR-style time-based revalidation.- Can also revalidate on-demand (
revalidateTag
,revalidatePath
).
- Stores
- Full Route Cache (server)
- Stores rendered RSC/HTML for static routes.
- Invalidated when data revalidates or on redeploy.
- Dynamic routes skip this.
- Router Cache (client)
- Stores prefetched RSC payloads for
<Link>
navigations. - Cleared by
router.refresh()
(client-only).
- Stores prefetched RSC payloads for
2. Controlling Caching
fetch
options
// Always cache (default for static)
await fetch(url, { cache: 'force-cache' })
// Never cache (dynamic)
await fetch(url, { cache: 'no-store' })
// ISR (revalidate every 60s)
await fetch(url, { next: { revalidate: 60 } })
On-demand revalidation
import { revalidateTag, revalidatePath } from 'next/cache'
// Inside server action or API route
await revalidateTag('products')
await revalidatePath('/dashboard')
๐ In a Server Action, this also clears the client Router cache instantly.
Route-level config
// Opt out of Full Route Cache (force dynamic render)
export const dynamic = 'force-dynamic'
// Skip all caches
export const revalidate = 0
// Default all fetches to no-store
export const fetchCache = 'default-no-store'
Also: using cookies()
or headers()
in a route marks it dynamic.
3. What Invalidates What?
- Data revalidation (time-based or on-demand) โ updates Data Cache + invalidates Full Route Cache.
- Redeploy โ clears Full Route Cache (not Data Cache).
router.refresh()
โ clears only the client Router Cache.
4. Browser vs Server fetch
- In browser โ
cache
controls the HTTP cache. - In Next.js server โ
cache
controls the Data Cache behavior.
5. Defaults
- Static rendering: Data Cache + Full Route Cache enabled.
- Dynamic rendering:
fetch
runs every request. <Link prefetch>
populates Router Cache automatically.
6. Quick Decision Table
Situation | What to do |
---|---|
Always serve fresh (auth dashboards) | fetch(..., { cache: 'no-store' }) or export const revalidate = 0 |
ISR (update every N seconds) | fetch(..., { next: { revalidate: N } }) |
On-demand revalidation (CMS updates) | Use revalidateTag / revalidatePath |
Force full dynamic rendering | export const dynamic = 'force-dynamic' |
Skip client cache after action | Call router.refresh() |
โก Use no-store
for truly dynamic, revalidate
for ISR, and revalidateTag/Path
for precise invalidation. Combine with route config to balance freshness vs performance.
How did you like this post?
๐0
โค๏ธ0
๐ฅ0
๐ค0
๐ฎ0