Bitlyst

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.
  • Data Cache (server, persistent)
    • Stores fetch results across requests.
    • Controlled by cache and next.revalidate.
    • force-cache โ†’ uses it.
    • no-store โ†’ skips it.
    • next.revalidate โ†’ ISR-style time-based revalidation.
    • Can also revalidate on-demand (revalidateTag, revalidatePath).
  • 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).

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

SituationWhat 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 renderingexport const dynamic = 'force-dynamic'
Skip client cache after actionCall 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
Next.js App Router Caching โ€” Cheat Sheet ยท Bitlyst