Incremental Static Regeneration Explained: Fast Sites That Still Update Instantly
Incremental Static Regeneration gets explained as "a middle ground between static and server-rendered," which undersells it — for most content-driven sites, ISR gives you static-site performance with dynamic-site freshness, and the tradeoff is smaller than it sounds.
The core mechanism
You set a revalidate interval on a page (say, 60 seconds). The first request after deploy serves a statically generated page instantly, straight from cache/CDN. After the revalidate window passes, the next request still gets the (now stale) cached page instantly — but triggers a regeneration in the background. Once that finishes, subsequent requests get the fresh version. Nobody ever waits on a regeneration; they just occasionally see content that's up to a revalidate-window old.
Why that tradeoff is usually fine
For a blog post, a pricing page, a services listing — content that changes occasionally, not per-request — "at most 60 seconds stale" is indistinguishable from "always fresh" to a real visitor, while every single request still gets CDN-cached, instant-load performance. You get server-rendered freshness without paying server-rendered latency on every request.
Where it's the wrong tool
Anything genuinely per-user or per-request — a dashboard showing the logged-in user's own data, a cart, search results scoped to a query string — shouldn't be ISR'd at all; that's what dynamic rendering or client-side fetching is for. Applying ISR there doesn't just fail to help, it actively serves the wrong user's cached data to someone else, which is a real bug, not just a missed optimization.
The gotcha that actually bites people
On-demand revalidation (calling revalidatePath/revalidateTag from a webhook or admin action after a content change) is what makes ISR feel truly instant instead of "eventually, within the window." Relying on the time-based interval alone means a content editor publishes a change and has to wait, confused, for up to the full revalidate window before seeing it live. Wiring the CMS's save action to trigger on-demand revalidation is what closes that gap — and it's the step people skip because the time-based version already "works."
Takeaway
ISR isn't a compromise you settle for — for content that changes occasionally and is read by many people, it's close to strictly better than either fully static or fully server-rendered. The two things to get right are choosing a sane revalidate window and wiring on-demand revalidation into your content-change events, not just relying on the timer.