Back to Writing
Growth status: Evergreen EvergreenUpdated: Jan 30, 20262 min read

Understanding Next.js Page Caching (with a real example)

Caching can be a tricky topic, especially when pages don’t update the way you expect. I recently ran into a situation on my /writing page where new articles would not appear immediately, even though individual posts showed up instantly. Diving into Next.js caching taught me a lot, and I want to share what I learned so others can avoid the same confusion

I recently ran into an interesting issue while working on the /writing page of my site. Whenever I added or updated articles, the changes did not show immediately. Oddly enough, the individual article pages updated as expected, but the listing page stayed stale.

After some digging, I realized this was not a bug. It was Next.js doing exactly what it is supposed to.

How Next.js caching works

Next.js (App Router) handles HTML caching at the edge in production. For statically prerendered pages, it sets Cache-Control: s-maxage=31536000, which is one year. This header tells CDNs and edge caches that they can serve the page without re-fetching for a long time. Browser cache headers such as no-cache do not override this because s-maxage takes priority for shared caches.

This explains why the listing page showed stale content while individual article pages, which are either dynamic or use revalidation, updated immediately.

How to control caching

Next.js provides a clean way to manage page freshness.

First, set revalidation for a page. In the page file, for example app/writing/page.tsx, add:

export const revalidate = 60; // seconds

The page is served from cache for 60 seconds. After 60 seconds, the next visitor triggers background regeneration. Visitors continue to get a fast response while the page updates.

For instant updates after saving content, use on-demand revalidation:

import { revalidatePath } from 'next/cache';
revalidatePath('/writing');

Call this in your article save logic, whether that is a CMS, API route, or webhook, to invalidate the cached page immediately.

Key lessons from my experience

Edge caching is powerful, but it can make pages seem stale if revalidation is not configured. Browser cache clearing or changing Nginx headers does not affect HTML caching for statically prerendered pages. The correct place to control page freshness is in the Next.js route itself, not the server or CDN alone.

By adding a single line of code to the route, I now get the perfect balance: fast cached pages that still update reliably when I add or edit content.

References

Next.js ISR and Self-hosting

Next.js Caching and Revalidation

Next.js Config and Headers

Update History

Jan 30, 2026How Next.js caching works
Jan 30, 2026How to control caching
Jan 30, 2026Key lessons from my experience

Share this writing