Alle Artikel
23. September 2026

Incremental static regeneration: how ISR works and when to use it

Incremental static regeneration caches pages instantly and rebuilds them in the background. Here is how time-based and on-demand ISR work, and when to use it.

What it is and why it matters

Incremental static regeneration (ISR) serves a prerendered, cached page instantly, then regenerates that page in the background on a schedule or an event, so visitors never wait on a full site rebuild. It sits between two older choices: rebuild every page ahead of time (static generation), or run every request live (server-side rendering).

The pattern underneath ISR is called stale-while-revalidate. A visitor gets the fast cached response first, and the regeneration work happens after, out of the request path. In Next.js, a route opts into ISR with a single line, export const revalidate = 60, paired with generateStaticParams to prerender the known paths at build time. Once that window passes, the next request still gets the cached page immediately, while a fresh version regenerates behind it. Once the new version finishes, later requests get the update, according to Next.js's own ISR guide, last updated in June 2026.

This matters most for founders, product leads and engineering managers deciding how a content-heavy site should render. A fully static build means every content change triggers a new deploy. Full server-side rendering means every visitor pays the cost of a fresh render, even when the underlying data barely changes. ISR fits the space between: content that updates on a schedule, not in real time. This blog runs on that exact pattern. New posts regenerate within minutes of publishing without a redeploy, which is as good a demonstration as any of why the tradeoff works.

How it works in practice

Time-based revalidation

The simplest form sets an interval. export const revalidate = 3600 invalidates the cache for that route at most once an hour. Next.js recommends a high interval, an hour rather than a second, and switching to fully dynamic rendering if a page genuinely needs real-time data. Set the number too low and ISR becomes an expensive imitation of server-side rendering, minus the benefit of always-fresh data.

On-demand revalidation

For anything event-driven, a database write, a CMS publish, a price change, revalidatePath invalidates a whole route by path, and revalidateTag invalidates by a tag attached to individual fetch calls or cached functions. Both are called from a server action or route handler, and in the App Router the actual regeneration happens on the next request rather than immediately. This is the more precise tool. Instead of guessing an interval, the cache clears exactly when the underlying data changes.

What happens on the hosting platform

On Vercel, a cache hit never touches the origin function at all: the CDN serves it directly. A cache miss forwards to a durable ISR cache that holds content for up to 31 days, and only invokes the function if that also misses. When a page revalidates, the new version propagates to every CDN region within 300ms, and simultaneous requests to the same uncached path collapse into a single function call instead of stampeding the origin. The response header x-nextjs-cache reports HIT, STALE, MISS or REVALIDATED, the fastest way to confirm a deploy is actually caching the way you expect.

Auditing a Next.js site's caching setup usually turns up the same handful of gaps as its crawlability issues. If you're reviewing both at once, our Next.js technical SEO audit checklist covers the rest of that list.

Error handling matters here too. If a background regeneration throws, Next.js keeps serving the last successfully generated version and retries on the next request rather than surfacing a broken page. Vercel applies the same principle at the platform level: a failed revalidation (a timeout, a non-2xx status outside the redirect and not-found range, or a function error) leaves the stale content in place and retries after a 30-second window. The practical effect is that a flaky upstream API or database rarely takes a cached page down. Visitors keep seeing the last good version while the system quietly tries again.

Tradeoffs and edge cases

Against full static generation, ISR removes the need to rebuild an entire site for one content change. Only the touched pages regenerate, which keeps build times from growing linearly with the size of the catalog. Leonardo.ai's build times dropped from ten minutes to two after moving user-generated content onto ISR, according to Vercel's own case study writeup.

Server-side rendering is the other comparison, and ISR wins on cost. Most responses stay at static speed, with a bounded staleness window instead of hitting the origin on every request. Stripe paired ISR with client-side caching to absorb 17 million edge requests at the launch of a Black Friday campaign, the kind of traffic spike SSR alone would struggle to serve cheaply.

Real edge cases are worth planning for ahead of time. A very short time-based window on a high-traffic route adds function invocations for a freshness gain most visitors will never notice; a longer interval, or on-demand revalidation triggered by the actual data change, is usually both cheaper and more accurate. Multi-instance, self-hosted deployments need a shared custom cache handler, because the default file-system ISR cache is per-instance: an on-demand revalidation call only clears the instance that received it, not the whole fleet.

The same lesson shows up at the data layer. If the underlying data is scoped per user or per tenant, for example through Supabase row level security, the cached HTML has to already reflect the right access scope before it gets cached, since ISR caches the rendered output, not a live query. A page built from a service-role query and then cached for every visitor will leak whatever that service-role query could see. The safe pattern is to keep ISR for genuinely public, shared content, and route anything user-specific or tenant-specific through dynamic rendering or a separate per-user data fetch that runs after the cached shell loads.

When we scope a client's rendering strategy, ISR is usually the default for anything that updates on a content-publish cadence rather than per request, and row-level security stays enforced at the data layer underneath it, not inside the cache. The two systems solve different problems. One controls who can read a row, the other controls how long a rendered page stays valid before it needs a fresh look.

ISR is the right default when content updates on a known schedule, minutes to hours, not when it needs to be correct to the second. Set the revalidation interval to match how often the content actually changes, not a guess, and reach for on-demand revalidation whenever the trigger is a real event: a publish, a price update, a write to the database. Get that pairing right and a site stays fast without turning every content change into a redeploy. If you're weighing ISR, SSR or a fully static build for an upcoming Next.js project, our web development team can walk through the tradeoffs for your specific data model.

Frequently asked questions

What is incremental static regeneration?

ISR is a caching strategy that serves a prerendered static page instantly, then regenerates it in the background after a set time interval or an on-demand trigger, so visitors never wait on a rebuild.

How is ISR different from server-side rendering?

SSR runs on every request, so every visitor waits on fresh data. ISR serves the cached page immediately and only regenerates in the background on a schedule or an event, trading a small window of staleness for consistently fast responses.

How often should a page revalidate?

An hour is a reasonable default, not a second. Short intervals on high-traffic routes add function invocations without a proportional freshness benefit; pages that need true real-time data are better served by dynamic rendering instead of ISR.

Does ISR work on every hosting platform?

ISR requires the Node.js runtime and isn't available with static export. Vercel adds platform-level features on top of the core APIs, durable 31-day cache storage, request collapsing, and CDN purges that propagate globally within 300ms, but self-hosted Node deployments support the underlying revalidate and on-demand APIs too.