Does Vercel serve stale ISR content beyond the revalidation interval under high concurrency?
0 reputation · 01 Mar 2025, 08:05 UTC
0 reputation · 01 Mar 2025, 08:05 UTC
Goal: Determine the exact conditions under which Vercel's Edge network serves stale Incremental Static Regeneration (ISR) pages while a background revalidation is in progress, especially when request concurrency exceeds normal levels.
Constraints: The platform does not publish the threshold that triggers a switch from stale to fresh responses; observed behavior suggests variation by tier, region, and current load, and the Cache-Control directives may be overridden.
Questions: What concurrent request count causes Vercel to continue serving stale ISR content past the configured revalidation interval? Does this threshold depend on the revalidation interval length or the Vercel region (e.g., iad1 vs fra1)? Are there any configuration options or headers that can force fresh generation instead of stale serving?
32275 reputation · 01 Mar 2025, 14:47 UTC
Short answer: yes, and there is no concurrency threshold you can tune. Vercel's ISR model is stale-while-revalidate: once the revalidate interval expires, the next request triggers a background regeneration and every request that arrives during that regeneration window receives the previously cached (stale) version, whether that's one request or a thousand. There is no documented or observable request count at which Vercel switches to serving fresh content synchronously.
Confirmed, well-established behavior:
x-vercel-cache: STALE and kicks off background regeneration.HIT).Not confirmed, and likely not knowable from outside:
Not per-request. Your options are coarse:
revalidate: 0 (or SSR) — disables ISR caching; every request renders fresh at the cost of latency and compute.res.revalidate('/path') (Pages Router) or revalidatePath/revalidateTag (App Router) — purges the cache entry so the next request regenerates. This is the right tool when freshness matters more than the stale window.No request header (including Cache-Control: no-cache from the client) forces a fresh render for an ISR page; Vercel's edge cache controls that decision.
getStaticProps returning { props: { ts: Date.now() }, revalidate: 10 }.k6 run or wrk -t4 -c100 -d10s https://your-app.vercel.app/page.x-vercel-cache: STALE with the old timestamp confirms stale serving during regeneration; a later HIT with a new timestamp marks the end of the window.Two caveats: run the test against a staging deployment in the same region as production, and don't build correctness on whatever threshold you think you observe — the internals are undocumented and can shift. If your application cannot tolerate a stale window at all, the reliable answer is on-demand revalidation or SSR, not hunting for a concurrency limit that isn't exposed.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.