ISR pages aren't stale because ISR is broken. They're stale because nobody visited them.
I run a Next.js content site on Vercel. A few hundred pages, revalidate set to 300 seconds, App Router, nothing exotic. I changed a number on one of the detail pages, waited the five minutes, reloaded, and saw the old number. Waited an hour. Still the old number. My first instinct was that ISR was broken. It wasn't. The behaviour is documented, it's just easy to misread — and the thing that…
In a recent account, a Next.js content site hosted on Vercel experienced stale content on several detail pages despite setting revalidate to 300 seconds. Initially, the developer believed ISR was broken, but upon investigation, it was determined that the pages were simply not being visited. The response headers provided crucial information to diagnose the issue quickly.
The x-nextjs-stale-time header indicated the revalidate value, while the age header showed how many seconds ago the cached entry was created. The x-vercel-cache header confirmed whether a fresh copy was served or an expired copy was served, prompting a regeneration in the background. Understanding that ISR regeneration is lazy and request-triggered, the developer discovered that pages with long tails were remaining stale for extended periods due to limited traffic.
By implementing on-demand revalidation, where data changes trigger an explicit revalidation of the affected page, the stale content issue was resolved. Lowering the revalidate value did not solve the problem, as it only added unnecessary load to popular pages that were already being visited frequently. Regularly checking the age of critical pages and implementing a script to alert when age exceeds a multiple of stale-time can help prevent stale content issues before users encounter them.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.