How caching works in Next.js

Tiger AbrodiTiger Abrodi
4 min read

The Four Caching Systems

1. Request Memoization

This is the most basic form of caching. When your code makes the same data request multiple times during a single page render, Next.js only executes that request once.

For example, if three components on your page need the same data, the actual fetch happens once, and the result is shared. This happens automatically when you use the fetch API in your components. The cache only lasts for the current request → once the page is sent to the user, this cache is cleared.

2. Data Cache

The Data Cache stores the results of fetch requests on the server across multiple user requests and even across deployments.

When you fetch data in a component, Next.js checks if that data is already in the Data Cache. If it is, it uses the cached data instead of making a new request to your data source. This makes your application faster and reduces load on your databases or APIs.

By default, data is cached indefinitely, but you can control this by setting revalidation rules (or opting out for a page):

// Cache the data, but revalidate it after one hour
fetch('https://api.example.com/data', { next: { revalidate: 3600 } })

// Don't cache this data at all
fetch('https://api.example.com/data', { cache: 'no-store' })

You can also trigger revalidation manually using revalidatePath or revalidateTag functions.

3. Full Route Cache

Next.js doesn't just cache data. It can cache entire rendered pages. When a route is statically rendered, Next.js saves:

  • The HTML of the page

  • The React Server Component Payload (a compact representation of your server components)

This means Next.js doesn't have to re-render these pages for each visitor. Instead, it serves the pre-generated content, making page loads very fast.

Routes are statically rendered by default unless you use dynamic features like cookies, headers, or uncached data fetches.

4. Router Cache

This cache exists in the user's browser memory during a session. When a user navigates between pages, Next.js stores the previously visited routes. This enables instant back/forward navigation without making new requests to the server.

This cache is temporary and only lasts during the user's session. It's cleared when the page is refreshed.

How These Caches Work Together

These caching systems don't work alone → they create a complete caching strategy:

When building your app, Next.js statically renders pages and stores them in the Full Route Cache.

  1. When fetching data, the Data Cache stores results to avoid repeated data fetches.

  2. During a single page render, Request Memoization ensures each unique data request only happens once.

  3. As users navigate your site, the Router Cache enables fast navigation between pages they've already visited.

Controlling Cache Behavior

You can control caching in several ways:

  • For data caching, use the cache and next.revalidate options with fetch.

  • For route caching, use dynamic functions like cookies() or headers() to make routes dynamic.

  • For time-based revalidation, use the revalidate option.

  • For on-demand revalidation, use revalidatePath or revalidateTag in Server Actions.

When you want fresh data, you have options:

  • Revalidate on a time interval

  • Revalidate on specific events

  • Opt out of caching entirely

Recap: The Four Next.js Caches

Request Memoization: Saves the results of fetch calls during a single page render. It prevents duplicate data fetches within the same component tree. This cache lasts only for the current request and is cleared once rendering completes. It happens automatically with no configuration needed.

Data Cache: Persists fetch results on the server across multiple user requests and deployments. This allows Next.js to reuse previously fetched data without hitting your data sources repeatedly. This cache is persistent until manually revalidated. Control it using fetch options like cache: 'no-store' to disable caching or next: { revalidate: seconds } to set time-based revalidation.

Full Route Cache: Stores pre-rendered HTML and React Server Component Payloads for entire routes. This cache eliminates the need to re-render pages for each visitor. It persists across requests and is invalidated on redeployment or when the Data Cache is revalidated. Routes become dynamic (not cached) when using dynamic functions like cookies, headers, or uncached data fetches.

Router Cache: Stores previously visited routes in the user's browser memory. This enables instant navigation between pages without additional server requests. This cache lasts for the user's session and is cleared on page refresh. Navigation with the <Link> component uses this cache automatically.

1
Subscribe to my newsletter

Read articles from Tiger Abrodi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tiger Abrodi
Tiger Abrodi

Just a guy who loves to write code and watch anime.