Articles

What Is Incremental Static Regeneration (ISR)?

ISR lets a static page be rebuilt in the background after deploy, on a timer or on demand, without a full site rebuild. How it works and its tradeoffs.

The Lycoris Team The Lycoris Team · · 5 min read
Abstract web platform diagram

Incremental Static Regeneration (ISR) is a rendering strategy that lets individual static pages be rebuilt after a site has already been deployed — on a timer, or on demand — without triggering a full site rebuild. It sits between two older extremes: pages that are static forever until the next full deploy, and pages that are rendered fresh on every request.

The gap ISR fills

To see why ISR exists, it helps to place it against the two strategies it sits between, covered in more detail in SSR vs SSG:

  • Static Site Generation (SSG) builds every page at deploy time. Pages are fast (served from a CDN, no server work per request) but stale until the next full build. A product catalog with thousands of pages means a full rebuild every time a single price changes.
  • Server-Side Rendering (SSR) builds each page fresh on every request. Content is always current, but every request pays the cost of rendering, and traffic spikes hit your rendering server directly.

ISR’s pitch: keep the speed of pre-built static pages, but let individual pages refresh themselves without forcing a rebuild of the entire site.

How it works

The mechanics vary slightly by framework, but the core pattern is consistent:

  1. A page is generated statically at build time, like normal SSG, and cached at the edge.
  2. That cached page is configured with a revalidation window — say, 60 seconds.
  3. When a request comes in after the window has elapsed, the stale cached version is served immediately (so the user never waits on a rebuild), while the page is regenerated in the background.
  4. Once regeneration finishes, the cache is updated. The next request gets the fresh version.

This pattern is often called stale-while-revalidate, and it’s the same idea behind the HTTP caching header of the same name — ISR is essentially that caching strategy applied to whole rendered pages instead of individual HTTP responses.

Some frameworks also support on-demand revalidation: instead of waiting for a timer, your backend calls an API to invalidate a specific page’s cache the moment its underlying data changes — for example, when a CMS webhook fires after an editor publishes a change.

On-demand vs time-based revalidation

Time-based (timer)On-demand (event-triggered)
TriggerElapsed time since last buildAn explicit API call or webhook
FreshnessBounded by the revalidation windowImmediate, tied to the actual change
SimplicitySet a number, doneRequires wiring a webhook or trigger
Best forContent that changes unpredictably or rarelyContent with a clear “this changed” event (CMS publish, price update)

Most production setups use both: a long time-based window as a safety net, plus on-demand revalidation for known change events, so a forgotten webhook doesn’t leave a page stale indefinitely.

What ISR doesn’t solve

ISR pages are still served to all visitors from the same cached copy — it’s not a mechanism for per-user personalization. A page that needs to show different content per logged-in user (a dashboard, a cart) generally isn’t a good ISR candidate; that’s still SSR or client-side data-fetching territory, sometimes handled with server actions for the mutation side.

It also doesn’t eliminate the “thundering herd” problem entirely — if a page gets a burst of concurrent requests right after its cache expires, most frameworks deduplicate the regeneration so only one rebuild happens rather than one per concurrent request, but this detail varies by implementation and is worth checking for any given framework and hosting target.

Caching layer matters as much as the framework

ISR only works if there’s a cache in front of the rendering layer that can serve a stale copy instantly while a fresh one is generated behind the scenes. In practice, that cache is usually a CDN edge node or a platform-managed cache sitting in front of your deployment — not something the framework implements from scratch. This is why ISR behavior can vary meaningfully between hosting providers running the same framework: the revalidation contract (serve stale, regenerate, swap) is only as reliable as the cache layer honoring it correctly, including for concurrent requests during the regeneration window.

This also means ISR interacts with other caching decisions on your site. A page using ISR still benefits from correct HTTP caching headers for its static assets — images, scripts, stylesheets — since those are typically fingerprinted and cached far more aggressively than the HTML shell itself, which is the piece ISR is actually managing the freshness of.

Choosing a revalidation window

There’s no universally correct interval — it’s a tradeoff between staleness tolerance and regeneration cost. A marketing page that rarely changes might use a window measured in hours; a product page with frequently updated pricing or stock counts might use something closer to a minute. Setting the window too short defeats much of ISR’s purpose, since pages end up regenerating almost as often as an SSR page would render — without the equivalent freshness guarantee, because a request landing exactly during the stale window still gets outdated content. Setting it too long risks visibly stale content for time-sensitive data, which is usually the signal to switch that specific page to on-demand revalidation instead of tuning the timer further.

Where you’ll encounter it

ISR was popularized by Next.js, but the underlying idea — pre-rendered pages with background regeneration — shows up under different names across the ecosystem. Astro’s on-demand rendering combined with edge caching, and various edge function platforms, can achieve equivalent behavior even without a feature called “ISR” specifically. The pattern matters more than the name: static-speed delivery with a bounded, background-refreshed staleness window.

The takeaway

ISR gives you the delivery speed of a fully static site with a page-level mechanism for staying current, without paying for a full rebuild on every content change. Use a time-based window as a baseline, layer on-demand revalidation for content with a clear change event, and reserve true SSR for pages that genuinely need per-request or per-user freshness.

Takina Takina · · 3 min read

Reflow vs Repaint: How Browsers Redraw Pages

Reflow recalculates layout; repaint just redraws pixels. Why the difference matters for animation performance and how to avoid triggering reflow.

#Web Development #Performance #Frontend
Takina Takina · · 4 min read

Interaction to Next Paint (INP) Explained

INP measures how long a page takes to visually respond to a click, tap, or keypress. What it counts, how it's scored, and how to bring it down.

#Performance #Web Development #Frontend