Skip to content
App Router...Data FetchingCaching and Revalidating

Caching and Revalidating

Caching

Caching is the process of storing data to reduce the number of requests made to the server. Next.js provides a built-in Data Cache for individual data requests, giving you granular control of caching behavior.

fetch requests

By default, fetch requests fetch fresh data at runtime.

To cache an individual fetch request, you can use the cache: 'force-cache' option:

// 'force-cache' is the default, and can be omitted
fetch('https://...', { cache: 'force-cache' })

To opt out of caching for individual fetch requests, you can use the cache: 'no-store' option:

layout.js | page.js
fetch('https://...', { cache: 'no-store' })

Advanced: If you have multiple fetch requests in a layout or page segment, you can configure the caching behavior of all data requests in the segment using the const dynamic = 'force-dynamic' or const fetchCache = 'force-no-store' Segment Config Options.

Data fetching libraries and ORMs

Whether a data request is cached will depend on the default semantics of your Data Fetching Library, Database Client, or ORM.

To cache specific requests, you can use the unstable_cache API:

import { unstable_cache as cache } from 'next/cache'
 
export async function getPosts() {
  cache()
 
  try {
    // Fetch Data
  } catch (error) {}
}

To opt specific requests out of caching, you can use the unstable_noStore API:

import { unstable_noStore as noStore } from 'next/cache'
 
export async function getTransactions() {
  // Prevent the response from being cached.
  // This is equivalent to in fetch(..., {cache: 'no-store'}).
  noStore()
 
  try {
    // Fetch Data
  } catch (error) {}
}

Revalidating data

Revalidation is the process of purging the Data Cache and re-fetching the latest data. This is useful when your data changes and you want to ensure you show the latest information while still benefiting from the speed of static rendering.

Cached data can be revalidated in two ways:

  • Time-based revalidation: Automatically revalidate data after a certain amount of time has passed. This is useful for data that changes infrequently and freshness is not as critical.
  • On-demand revalidation: Manually revalidate data based on an event (e.g. form submission). On-demand revalidation can use a tag-based or path-based approach to revalidate groups of data at once. This is useful when you want to ensure the latest data is shown as soon as possible (e.g. when content from your headless CMS is updated).

Time-based revalidation

To revalidate data at a timed interval, you can use the next.revalidate option of fetch to set the cache lifetime of a resource (in seconds).

fetch('https://...', { next: { revalidate: 3600 } }) // revalidate at most every hour

Alternatively, to revalidate all requests in a route segment, you can use the Segment Config Options.

layout.js | page.js
export const revalidate = 3600 // revalidate at most every hour

Learn how time-based revalidation works

Good to know:

  • If you have multiple fetch requests in a statically rendered route, and each has a different revalidation frequency. The lowest time will be used for all requests.
  • For dynamically rendered routes, each fetch request will be revalidated independently.
  • To save server resources, we recommend setting a high revalidation time whenever possible. For instance, 1 hour instead of 1 second. If you need real-time data, consider switching to dynamic rendering or client-side data fetching.

On-demand revalidation

Data can be revalidated on-demand with the revalidatePath and revalidateTag APIs.

Use revalidatePath in Server Actions or Route Handler to revalidate data for specific routes:

import { revalidatePath } from 'next/cache'
 
export default async createPost() {
  try {
    // Mutate data
    revalidatePath('/posts')
  } catch(error) {}
 
}

Use revalidateTag to revalidate fetch requests across routes.

  1. When using fetch, you have the option to tag cache entries with one or more tags.
  2. Then, you can call revalidateTag to revalidate all entries associated with that tag.

For example, the following fetch request adds the cache tag collection:

app/page.tsx
export default async function Page() {
  const res = await fetch('https://...', { next: { tags: ['collection'] } })
  const data = await res.json()
  // ...
}

You can then revalidate this fetch call tagged with collection by calling revalidateTag:

@/app/actions.ts
'use server'
 
import { revalidateTag } from 'next/cache'
 
export default async function action() {
  revalidateTag('collection')
}

Learn how on-demand revalidation works.

Error handling and revalidation

If an error is thrown while attempting to revalidate data, the last successfully generated data will continue to be served from the cache. On the next subsequent request, Next.js will retry revalidating the data.