Implementing Incremental Static Regeneration (ISR) in a Jamstack Site with Next.js
Learn how to add Incremental Static Regeneration to a Jamstack site with Next.js: requirements, minimal page example, trust boundaries, operational checks, failure modes, and when to switch strategies.
16 Jan 2026, 01:04 UTC

Problem and Takeaway
You need a Jamstack site that shows fresh data without rebuilding the whole site on every change. Rebuilding on each update wastes build minutes and delays content visibility. The takeaway is that Incremental Static Regeneration (ISR) lets you keep the performance benefits of static generation while updating pages in the background after a set interval, serving stale content until the new version is ready.
Requirements
- Node.js runtime version 14 or newer.
- Next.js framework version 9.4 or newer (ISR was introduced in 9.4).
- A headless CMS or any data source reachable over HTTP(S) that returns JSON.
- A deployment platform that provides edge caching and supports ISR: Vercel, Netlify, or Cloudflare Pages.
- Basic familiarity with the command line and Git for pushing changes.
Smallest Suitable Design
The minimal implementation consists of a single page that uses getStaticProps with a revalidate value. At build time Next.js generates the page with the data fetched from the CMS. After the interval expires, the first request triggers a background regeneration while the edge continues to serve the previously generated (stale) HTML.
Example Page Component
import { GetStaticProps } from 'next';
export default function TimestampPage({ timestamp }) {
return (
Current server time
{timestamp}
);
}
export const getStaticProps: GetStaticProps = async () => {
// Replace with your real CMS endpoint
const res = await fetch('https://example-mock-api.com/timestamp');
if (!res.ok) {
// If the API fails, we still want to return something so the page does not crash.
return { props: { timestamp: 'unavailable', revalidate: 10 } };
}
const data = await res.json();
return {
props: { timestamp: data.now },
// Revalidate at most every 10 seconds
revalidate: 10,
};
};
Deploy this page to your chosen platform. No additional server code is required; the ISR logic lives inside the Next.js serverless function that Vercel/Netlify/Cloudflare Pages provides.
Trust and Data Boundaries
Treat the CMS/API as an untrusted external source. All data fetched inside getStaticProps must be validated and sanitized before it is inserted into the page. For example, if the API returns HTML fragments, run them through a sanitizer like dompurify before rendering. The ISR regeneration runs in the same trusted serverless function boundary as the initial build, so no extra trust zone is introduced.
Operational Checks
To confirm that ISR is working as expected:
- Inspect the
X-Nextjs-Cacheresponse header. Values you should see:MISSon the first request (page generated at build time).HITfor subsequent requests while the cache is fresh.STALEafter the revalidate interval has passed but before background regeneration finishes.
- Monitor edge logs (Vercel Analytics → Edge Middleware, Netlify Edge Logs, or Cloudflare Pages logs) for a background request to the same URL that occurs after the interval while the edge continues to serve the cached response.
- Set an alert on failed revalidation attempts (e.g., non‑200 responses from the background fetch) or on a sudden rise in cache misses, which could indicate a mis‑configured CMS endpoint.
Failure Modes and Conditions That Would Change the Design
ISR gracefully degrades when the upstream API is unavailable:
- If the API fails during a background revalidation, the edge continues to serve the last successfully fetched stale page. No error is shown to the visitor.
- If the outage lasts longer than the revalidate interval, the page will remain stale until the API recovers and a successful revalidation occurs. For content that must be accurate within seconds, this staleness may be unacceptable.
- If you discover that you need sub‑second freshness (e.g., real‑time tickers), ISR is not suitable because the minimum practical revalidate interval is limited by the edge’s ability to schedule background jobs. In that case you would switch to Server‑Side Rendering (SSR) or edge‑function rendering.
- Mis‑configured cache‑control headers (e.g., setting
Cache-Control: privateor disabling the platform’s edge cache) cause ISR to fall back to a full rebuild on each request, increasing cost and latency. Verify that the platform’s edge caching is enabled and that you are not overriding it with conflicting headers.
Practical Verification Steps
- Create a fresh Next.js project:
npx create-next-app@latest isr-demo --typescript(or omit TypeScript if you prefer JavaScript). - Replace the generated
pages/index.jswith the example component above, adjusting the mock API URL to a service you control (e.g., a simple Vercel serverless function that returns{ "now": new Date().toISOString() }). - Build and preview locally:
npm run build && npm run start. Requesthttp://localhost:3000several times and note theX-Nextjs-Cacheheader (you can view it withcurl -I http://localhost:3000). You should seeMISSthenHIT. - Deploy to Vercel (requires a Vercel account with repo access):
vercel --prod. After deployment, run the same curl command against the production URL. - Wait longer than the revalidate interval (e.g., 12 seconds) and request again. The header should show
STALEfollowed by a background request visible in Vercel’s Edge Logs. - Simulate an API failure by temporarily blocking the mock endpoint (e.g., using a firewall rule or editing the function to throw). Request the page; you should still see the last good timestamp and the header remain
HITorSTALEuntil the block is removed and a successful revalidation occurs.
Limitations
- ISR relies on the hosting platform’s edge cache. If you move to a provider that does not support edge‑based ISR (e.g., a traditional static‑host without CDN edge compute), you would lose the incremental benefit and need to fall back to full rebuilds.
- Low revalidate values increase the frequency of serverless function invocations, which can raise cost on platforms that charge per execution. Monitor usage and adjust the interval based on content freshness requirements and budget.
- Because the stale‑while‑retry model serves potentially outdated data, any business rule that demands immediate consistency (e.g., flash‑sale pricing) must be evaluated against the chosen revalidate window.
When to Reconsider the Design
If you observe any of the following, consider moving away from ISR:
- Content must be updated within a window shorter than your feasible revalidate interval (e.g., sub‑second).
- Your API imposes strict rate limits that would be exceeded by frequent background revalidations.
- You notice a pattern of stale content causing user‑visible issues and the business cannot tolerate the risk.
- Your deployment platform changes its pricing or removes edge‑compute support, making ISR economically unviable.
In those cases, evaluate SSR (using getServerSideProps) or edge‑rendering strategies that generate the page on every request but still benefit from CDN caching of static assets.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.