Next.js caching on your own server: ISR, the data cache and CDN headers
- Where the cache lives
- Multiple replicas
- Cache-Control headers
- On-demand revalidation
- Build time vs runtime
- Image optimization
- Test before trusting
Next.js caching works out of the box on Vercel because the platform wires it into its own infrastructure. On your own server, most of it still works, but a few assumptions change. Knowing them prevents stale pages and confusing deploys.
Where the cache lives
With next start or the standalone server, incremental static regeneration (ISR) and the data cache are stored on the local filesystem, inside .next/cache. In a container, that directory disappears on every deploy unless you mount it on a volume.
That is often fine: a fresh deploy starting with an empty cache simply regenerates pages on first request. It matters if regeneration is expensive or if you run several replicas.
Multiple replicas
Each replica keeps its own cache. One may serve a fresh page while another serves a stale one, and revalidatePath or revalidateTag called on one replica does not reach the others. Options:
- Run a single replica, which is enough for many apps
- Configure a shared cache handler, for example backed by Redis, using the
cacheHandleroption - Avoid ISR for pages that must be consistent and render them dynamically
Cache-Control headers
Next.js sets s-maxage and stale-while-revalidate headers for ISR pages. If you put a CDN in front, it will respect these. Without a CDN, browsers mostly ignore s-maxage, so the Node server handles every request, which is usually fine.
Static assets under /_next/static/ have hashed names and long cache headers. Serve them directly from the proxy or a CDN for a quick win.
On-demand revalidation
Webhooks from a CMS that call a revalidation route work the same as on Vercel, as long as the request reaches the replica that holds the cache. With a single replica, no extra work is needed.
Build time vs runtime
Pages rendered at build time contain data from the build moment. If the build runs in CI without access to production data, those pages may be empty or wrong. Either give the build access to the data it needs or make those pages dynamic.
Image optimization
next/image optimization works on self-hosted servers and caches results on disk. Install sharp in the production image for speed, and mount the cache if you want it to survive deploys.
Test before trusting
After deploying, change content in your CMS, trigger revalidation and confirm the page updates. Then restart the container and check again.
For the rest of the setup, from standalone output to HTTPS, see this guide to deploying Next.js to a VPS.
Disclosure: I work on Peon.
Write a comment