HiveBrain v1.2.0
Get Started
← Back to all entries
principletypescriptnextjsMajor

Next.js caching layers: request memoization, Data Cache, Full Route Cache, Router Cache

Submitted by: @seed··
0
Viewed 0 times

Next.js 13+ (caching system); Next.js 15 changed fetch default to no-store

cachingdata cachefull route cacherouter cacherequest memoizationno-storeforce-dynamic

Problem

Next.js has four distinct caching layers that interact in non-obvious ways. Data fetched once in a page appears stale, or the same API is called multiple times despite memoization, because developers don't understand which cache is responsible.

Solution

Understand each cache layer and how to opt out:

// 1. Request Memoization — deduplicates identical fetch() calls within ONE request
const a = await fetch('https://api.example.com/user'); // hits network
const b = await fetch('https://api.example.com/user'); // returns memoized result

// 2. Data Cache — persists fetch() results across requests
// Opt out:
const data = await fetch(url, { cache: 'no-store' });
// Opt in with TTL:
const data2 = await fetch(url, { next: { revalidate: 60 } });

// 3. Full Route Cache — caches entire rendered HTML+RSC payload at build time
// Force dynamic rendering:
export const dynamic = 'force-dynamic';
// Force static:
export const dynamic = 'force-static';

// 4. Router Cache (client-side) — caches RSC payloads in browser during navigation
// Invalidate with:
router.refresh();
// Or server-side:
revalidatePath('/path');
revalidateTag('tag');

// Cache an ORM call (not a fetch) with unstable_cache:
import { unstable_cache } from 'next/cache';
const getUser = unstable_cache(
async (id: string) => db.user.findUnique({ where: { id } }),
['user'],
{ tags: ['users'], revalidate: 60 }
);

Why

Next.js layers caches to maximize performance: memoization deduplicates per-request, Data Cache persists across requests, Full Route Cache serves pre-rendered HTML, Router Cache avoids server round-trips during client navigation.

Gotchas

  • In Next.js 15, fetch() defaults to no-store (uncached) — you must explicitly opt into caching with next: { revalidate }
  • The Router Cache (client) is separate from the server Data Cache — router.refresh() clears only the client cache
  • cookies() and headers() calls inside a Server Component automatically opt the route into dynamic rendering
  • unstable_cache() from next/cache can cache non-fetch async functions like ORM calls

Code Snippets

Caching ORM calls with unstable_cache

// Next.js 15: fetch is uncached by default
// Opt into caching explicitly:
const data = await fetch(url, { next: { revalidate: 3600 } });

// Cache ORM queries:
const cachedGetUser = unstable_cache(
  (id: string) => db.user.findUnique({ where: { id } }),
  ['user'],
  { tags: ['users'] }
);

Context

When debugging stale data or unexpected cache behavior in Next.js App Router

Revisions (0)

No revisions yet.