On-Demand Revalidation: Fixing the Jamstack Rebuild Bottleneck Without Full Deploys
Large Jamstack sites often hit a wall when a single content edit triggers a full rebuild. On-demand revalidation lets you regenerate only the affected paths, keeping build times constant as your site grows.
24 Jan 2026, 07:23 UTC

The rebuild wall: when one typo costs a full build
Jamstatic generators promise fast pages because HTML is built ahead of time. That promise holds until your page count grows. A 10,000-page product catalog can turn a five-minute build into a thirty-minute build, and every content edit—even a missing comma—waits in that queue. Content editors stop trusting the pipeline, and teams start hand-editing files in the CMS just to avoid the wait.
The useful takeaway is that you do not have to choose between static speed and fresh content. On-demand revalidation (often called incremental static regeneration) lets a CMS webhook or API call invalidate and regenerate only the affected paths. Build time stops scaling linearly with total page count because a single edit rebuilds one page, not the whole site.
How on-demand revalidation changes the deploy contract
In a traditional Jamstack workflow, a git push or CMS publish triggers a full site generation. The CDN cache is purged globally, and every page is re-rendered from templates and data sources. On-demand revalidation breaks that coupling. The framework keeps a render cache at the origin, and an authenticated request tells it, "This specific path changed; regenerate it now."
The mechanism differs by tool. Next.js exposes a revalidation utility inside an API route that purges the CDN cache for that path and serves fresh HTML on the next request. Astro and other generators offer comparable incremental rendering modes. The exact API name and behavior vary by framework and version, so confirm the mechanism for your generator before writing code.
Worked example: a Next.js webhook route
This example assumes a Next.js project using the Pages Router API routes convention. If you are on the App Router, the equivalent utilities are revalidatePath and revalidateTag from next/cache, and the route signature is different.
Create a file at pages/api/revalidate.ts. This route will receive a POST from your CMS when content changes.
import type { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// 1. Check the shared secret to prevent unauthorized cache purges
if (req.query.secret !== process.env.REVALIDATE_SECRET) {
return res.status(401).json({ message: 'Invalid token' });
}
// 2. Validate the path parameter to avoid cache injection
const path = req.query.path as string;
if (!path || !path.startsWith('/')) {
return res.status(400).json({ message: 'Missing or invalid path' });
}
try {
// 3. Regenerate only this path and purge its CDN cache
await res.revalidate(path);
return res.json({ revalidated: true, path });
} catch (err) {
return res.status(500).json({ message: 'Error revalidating' });
}
}
Run this locally with next dev to verify the route responds, then deploy it to your hosting provider. In your CMS, configure a webhook that POSTs to https://<YOUR_DOMAIN>/api/revalidate?secret=<YOUR_REVALIDATE_SECRET>&path=/products/example-slug whenever an entry is published or updated.
Required permissions are minimal: deploy access to push the API route, and CMS admin rights to register the webhook. Expected checks are straightforward—your hosting logs should show a 200 response from the webhook, and the next request to /products/example-slug should return freshly rendered HTML. The main risks are leaking the secret in a public repository and allowing arbitrary path values, so keep the token in an environment variable and validate the path prefix.
The stale-while-revalidate window and other limits
On-demand revalidation does not make every request hit the origin. By default, after invalidation the first request may still receive cached HTML while regeneration happens in the background. This is the stale-while-revalidate window: users get a fast response, but it may be one render behind the CMS. If your content requires strict consistency, you must choose a strategy that blocks the first request until fresh HTML is ready, accepting higher latency for that one visitor.
Another limitation is scope. Revalidation fixes content edits; it does not eliminate full rebuilds when templates, layouts, or shared components change. A design tweak to a header still requires a complete regeneration because every page depends on that layout.
CDN configuration can also mislead you. Aggressive cache TTLs or origin shielding may mask regeneration latency, making a staging test look faster than production reality. Configure staging and production cache layers identically before drawing conclusions.
Verify it before you trust it
Deploy a small staging site with at least two content types. Measure full-rebuild duration first, then trigger a single-path revalidation via the CMS webhook and measure again. Timestamp three moments: the CMS publish, the webhook receipt in your function logs, and the first fresh page view. Compare CDN cache hit ratios and origin render times before and after enabling incremental rendering.
If the first post-revalidation request still serves stale HTML, your CDN TTL or revalidation mode is the likely culprit, not the webhook. Adjust the cache strategy, re-test, and only then roll the pattern out to your largest content collections.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.