cacheLife profiles
Fifteen profiles — seven built in, eight defined in next.config.ts — each caching the same numeric probe. Grouped by what their lifetime does to prerendering rather than by duration.
Four of them (probe-*) exist only to sit on either side of a documented threshold, so you can see the boundary rather than take it on faith.
What to check
Which ones made it into the HTML. After a build, run curl -s localhost:3000/cache-life | grep -o 'data-fallback="[^"]*"' | sort -u. It lists exactly the profiles that could not be prerendered, and it should be the first group and nothing else.
Which ones move. Reload every few seconds. The short-window profiles change value on their own schedule; max and weeks never will.
The enforcement. Move any panel out of the first group and into a group without a Suspense boundary, then build. It fails and names the component.
App Shell. The difference between the last two groups only shows up in prefetching — see /prefetch for how to observe it in the network tab.
The profiles
| profile | stale | revalidate | expire | prerender |
|---|---|---|---|---|
| default | 5m | 15m | never | prerendered-shellFramework default when no cacheLife is called. |
| seconds | 30s | 1s | 1m | dynamic-holeThe only preset that falls below a threshold — its 1min expire keeps it out of prerenders. |
| minutes | 5m | 1m | 1h | prerendered-shellFrequently updated content. |
| hours | 5m | 1h | 1d | prerendered-shellSeveral updates a day. |
| days | 5m | 1d | 7d | prerendered-shellDaily updates. |
| weeks | 5m | 7d | 30d | prerendered-shellWeekly updates. |
| max | 5m | 30d | 365d | prerendered-shellEffectively permanent. What you want for immutable upstreams. |
| short(custom) | 30s | 1m | 5m | prerendered-no-shellPre-existing project profile. Sits right on the expire boundary at exactly 300s. |
| blog(custom) | 1m | 5m | 1h | prerendered-no-shellPre-existing project profile. Prerendered, but excluded from the App Shell. |
| isr-15(custom) | 30s | 15s | 10m | prerendered-no-shellFast ISR window — background regeneration is observable in about 15 seconds. |
| isr-60(custom) | 30s | 1m | 30m | prerendered-no-shellOne minute ISR window, for comparison against isr-15. |
| probe-no-prerender-stale(custom) | 10s | 1m | 10m | dynamic-holestale below 30s — excluded from prerenders, so it becomes a dynamic hole. |
| probe-no-prerender-expire(custom) | 30s | 20s | 2m | dynamic-holeexpire below 5min — also excluded from prerenders. |
| probe-no-shell(custom) | 1m | 2m | 15m | prerendered-no-shellstale between 30s and 5min — prerendered, but kept out of the App Shell. |
| probe-shell(custom) | 10m | 2m | 1h | prerendered-shellstale at or above 5min — prerendered and App Shell eligible. |
stale is a client-router concern: how long the browser reuses cached content without asking the server. revalidate is when the server starts regenerating in the background. expire is the point past which a request has to wait. Only stale and expire affect prerendering.
Dynamic holes — dynamic hole — resolved at request time
<Suspense> boundary. They are still shared cache entries — two visitors within the window get the same number — they just are not in the static HTML.seconds
suspense fallbackThe only preset that falls below a threshold — its 1min expire keeps it out of prerenders.
probe-no-prerender-stale
suspense fallbackstale below 30s — excluded from prerenders, so it becomes a dynamic hole.
probe-no-prerender-expire
suspense fallbackexpire below 5min — also excluded from prerenders.
Prerendered, not App Shell eligible — prerendered, excluded from App Shell
partialPrefetching prefetches. No Suspense boundary needed.short
use cache- cacheLife
- short
- upstream
- 411ms
ran at exec 13ls50age …
probe 646,056
30s stale · 1m revalidate · 5m expire — Pre-existing project profile. Sits right on the expire boundary at exactly 300s.
blog
use cache- cacheLife
- blog
- upstream
- 419ms
ran at exec 96j5jyage …
probe 941,308
1m stale · 5m revalidate · 1h expire — Pre-existing project profile. Prerendered, but excluded from the App Shell.
isr-15
use cache- cacheLife
- isr-15
- upstream
- 326ms
ran at exec svaopkage …
probe 236,059
30s stale · 15s revalidate · 10m expire — Fast ISR window — background regeneration is observable in about 15 seconds.
isr-60
use cache- cacheLife
- isr-60
- upstream
- 404ms
ran at exec gl7d9eage …
probe 503,521
30s stale · 1m revalidate · 30m expire — One minute ISR window, for comparison against isr-15.
probe-no-shell
use cache- cacheLife
- probe-no-shell
- upstream
- 525ms
ran at exec fyw1z5age …
probe 81,411
1m stale · 2m revalidate · 15m expire — stale between 30s and 5min — prerendered, but kept out of the App Shell.
Prerendered and App Shell eligible — prerendered and App Shell eligible
default
use cache- cacheLife
- default
- upstream
- 392ms
ran at exec gl3b24age …
probe 742,136
5m stale · 15m revalidate · never expire — Framework default when no cacheLife is called.
minutes
use cache- cacheLife
- minutes
- upstream
- 404ms
ran at exec b295vrage …
probe 524,932
5m stale · 1m revalidate · 1h expire — Frequently updated content.
hours
use cache- cacheLife
- hours
- upstream
- 320ms
ran at exec fsxxusage …
probe 704,917
5m stale · 1h revalidate · 1d expire — Several updates a day.
days
use cache- cacheLife
- days
- upstream
- 378ms
ran at exec y7xhqbage …
probe 912,481
5m stale · 1d revalidate · 7d expire — Daily updates.
weeks
use cache- cacheLife
- weeks
- upstream
- 527ms
ran at exec c4prftage …
probe 624,869
5m stale · 7d revalidate · 30d expire — Weekly updates.
max
use cache- cacheLife
- max
- upstream
- 374ms
ran at exec tyru5kage …
probe 60,253
5m stale · 30d revalidate · 365d expire — Effectively permanent. What you want for immutable upstreams.
probe-shell
use cache- cacheLife
- probe-shell
- upstream
- 395ms
ran at exec ju9u95age …
probe 472,730
10m stale · 2m revalidate · 1h expire — stale at or above 5min — prerendered and App Shell eligible.