staleTimes
Set how long the client router reuses a prefetched segment before refetching it.
experimental?: { staleTimes?: { dynamic?: number; static?: number } }- Added in Next.js v14.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$dynamicoptional | number= 0 | Seconds a segment stays reusable in the client cache when the page is neither statically generated nor fully prefetched. |
$staticoptional | number= 300 | Seconds a segment stays reusable for statically generated pages, for Link with prefetch={true}, and for router.prefetch calls. |
Changelog
- PHP v14.2.0Experimental staleTimes introduced.
- PHP v15.0.0The dynamic staleTimes default changed from 30s to 0s.
After a client-side navigation, the App Router keeps the React payload for the visited page segments in memory. staleTimes sets how long those entries stay reusable before the router goes back to the server. Values are seconds.
Which value applies
static covers statically generated pages, <Link prefetch={true}>, and router.prefetch() — it defaults to 5 minutes. dynamic covers everything else and defaults to 0, meaning no reuse; it was 30 seconds before Next.js 15. Loading boundaries are reusable for the static period.
When to reach for it
Raise dynamic when users move back and forth between a list and its detail pages and each return trip refetches. Lower static when a mostly-static page shows data that must not be minutes old.
What trips people up
- It is global. Per-scope control belongs to
cacheLife'sstale— and changingstaleTimes.staticalso changes thedefaultprofile'sstale. - Raising
dynamicis how you get an updated record still showing its old values after navigating away and back. CallingrevalidatePath,revalidateTag,updateTagorrefreshfrom a Server Action clears the client cache immediately. - It does not change partial rendering — shared layouts are still not refetched on every navigation — and does not change back/forward behavior.
- Still experimental.
Example
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
staleTimes: {
dynamic: 30,
static: 180,
},
},
}
export default nextConfigWhen to use it
- Restore the Next.js 14 feel after the dynamic default dropped from 30s to 0s in 15.
- Stop a list/detail flow from refetching on every back navigation.
- Shorten how long a prerendered page may serve a figure that changes often.
Frequently asked questions
Why does my page refetch on every back navigation in Next.js 15?
Because the dynamic staleTimes default changed from 30 seconds to 0 in v15.0.0, so dynamic segments are no longer reused from the client cache. Set experimental.staleTimes.dynamic to 30 to restore the previous behavior.
Why does the client router still show stale data after a mutation?
The client cache is serving a segment that is still within its stale window. Call revalidatePath, revalidateTag, updateTag or refresh from the Server Action that performed the mutation — any of them clears the entire client cache immediately, bypassing staleTimes.
What is the difference between staleTimes and cacheLife's stale?
staleTimes is a single global setting for the client router cache, while cacheLife sets stale per cached function or component. They are connected: updating staleTimes.static also updates the stale value of the default cacheLife profile.
More examples
Restoring the pre-15 dynamic behavior
If navigation felt instant on Next.js 14 and started refetching after the 15 upgrade, this is the change behind it. Setting dynamic back to 30 restores the old feel at the cost of showing data up to 30 seconds old on a return visit.
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
staleTimes: {
// Next.js 14 used 30; the default became 0 in 15
dynamic: 30,
},
},
}
export default nextConfigKeeping a mutation visible after navigation
With a raised dynamic stale time, navigating back to the project list after a rename would show the old name until the entry expired. Revalidating from the Server Action clears the whole client cache on the spot, which is why a longer stale time is safe as long as mutations revalidate.
'use server'
import { updateTag } from 'next/cache'
import { db } from '@/lib/db'
export async function renameProject(id: string, name: string) {
await db.projects.update(id, { name })
// Clears the client cache immediately, regardless of staleTimes
updateTag(`project-${id}`)
}Fresher data on a static page
A prerendered page carrying a live figure — a queue depth, a seat count — can otherwise sit in the client cache for five minutes. Lowering static shortens that, but a 30-second floor is enforced so prefetched links stay usable; going below it will not make navigations fresher.
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
staleTimes: {
// Default is 300; 30 is the enforced floor for prefetched entries
static: 30,
},
},
}
export default nextConfig
Discussion