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:
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 theconst dynamic = 'force-dynamic'
orconst 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.
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.
- When using
fetch
, you have the option to tag cache entries with one or more tags. - Then, you can call
revalidateTag
to revalidate all entries associated with that tag.
For example, the following fetch
request adds the cache tag collection
:
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
:
'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.
Was this helpful?