Skip to content

fix(cloudflare): stabilize staged Worker before CDN warmup - #3038

Closed
james-elicx wants to merge 1 commit into
codex/rsc-prewarm-pages-i18n-discoveryfrom
codex/rsc-prewarm-staged-readiness
Closed

fix(cloudflare): stabilize staged Worker before CDN warmup#3038
james-elicx wants to merge 1 commit into
codex/rsc-prewarm-pages-i18n-discoveryfrom
codex/rsc-prewarm-staged-readiness

Conversation

@james-elicx

Copy link
Copy Markdown
Member

Summary

  • wait for version-override routing to remain on the uploaded build before sending any real CDN warm key
  • use unique no-cache readiness queries so a probe can never satisfy a later probe from cache
  • keep each canonical full/loading/HTML warm request single-shot after readiness, with existing failed-key retry behavior unchanged
  • fail strict deployment before promotion when readiness cannot be established; non-strict deployment promotes and warms the untouched plan afterward

Root cause

The deployed proof failed twice while staging was still visibly routing a mix of the seed and uploaded Workers. In the second attempt, the loading-shell key accepted immediately during that mixed phase later missed, while the full key that reached the uploaded build only after six attempts later hit. URL, query, Vary fields, build ID, version UUID, host, and TTL matched. The existing 15-second post-fill delay occurred too late to make an early transitional fill reusable.

Scope

This changes only Cloudflare CDN warmup orchestration and its focused tests. It does not change client RSC identity, ISR eligibility/discovery, middleware, dev mode, TPR, cache adapters, or general request handling.

Validation

  • 77 focused Cloudflare warm/deploy/version tests passed
  • vp check passed across 3,104 formatted files and 1,315 lint/typechecked files
  • vinext build passed
  • @vinext/cloudflare build passed

References

@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues

@pkg-pr-new

pkg-pr-new Bot commented Aug 22, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@3038
npm i https://pkg.pr.new/create-vinext-app@3038
npm i https://pkg.pr.new/@vinext/types@3038
npm i https://pkg.pr.new/vinext@3038

commit: f6cd029

@github-actions

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
workers-cache preview production
web preview production

@github-actions

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared f6cd029 against base 29dab17 using alternating same-runner rounds. Next.js was unchanged and skipped.

1 improved · 0 regressed · 5 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 142.2 KB 142.2 KB ⚫ -0.0%
Client entry size (gzip) vinext 129.5 KB 129.5 KB ⚫ -0.0%
Dev server cold start vinext 2.20 s 2.17 s 🟢 -1.8%
Production build time vinext 2.42 s 2.43 s ⚫ +0.2%
RSC entry closure size (gzip) vinext 116.0 KB 116.0 KB ⚫ -0.0%
Server bundle size (gzip) vinext 197.5 KB 197.5 KB ⚫ -0.0%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head


for (let attempt = 0; attempt < maxAttempts; attempt++) {
const url = buildWarmupUrl(options.targetUrl, probePath);
url.searchParams.set(STAGED_READINESS_QUERY_PARAM, `${probeId}-${attempt}`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Keep the readiness nonce out of userland routing

This parameter is not stripped from the request: the App Router hides only _rsc before middleware/rendering, and Pages Router also receives this query unchanged. A middleware or page that rejects unknown parameters or branches on searchParams can therefore redirect/error on every probe even though the canonical warm request is healthy. In strict mode that blocks promotion; in non-strict mode it incurs the full readiness wait and fallback. Please preserve the unique edge key while removing this reserved parameter before userland, or probe through a route-insensitive readiness endpoint.

deploymentId: options.deploymentId,
expectedBuildId: options.expectedBuildId,
expectedRscBuildId: options.expectedRscBuildId,
timeoutMs: options.warmCdnTimeout,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Honor the configured staged retry budget

warmCdnRetries is the existing override for staged propagation (the CLI documents a default of 60 only when it is unset), but this call never maps it to maxAttempts. As a result, even --warm-cdn-retries=0 now performs 60 serial readiness probes; with the default 10-second per-request timeout, an operator who requested no retries can wait about 11 minutes. Preserve the 60-attempt default, but derive the readiness limit from an explicitly supplied retry count or expose and wire a separate readiness budget.

if (!readiness.ready) {
const message = `CDN warmup could not verify staged Worker readiness: ${readiness.error}.`;
if (options.warmCdnStrict) throw new Error(message);
console.warn(` ${message} Warming after promotion instead.`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not succeed when no-promote makes fallback impossible

When readiness fails non-strictly, this leaves the full plan untouched and promises to warm it after promotion. With warmCdnPromote === false, however, the early return below runs before remainingWarmPlan is processed, so the command succeeds after probes without sending any canonical warm request. That contradicts the --warm-cdn-no-promote contract of leaving a warmed version staged. Treat readiness failure as fatal when promotion is disabled (as the no-staging branch already does), or provide a real staged fallback before returning.

@ask-bonk

ask-bonk Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Submitted 3 inline findings. Focused test suite passed: 24/24.

github run

@james-elicx

Copy link
Copy Markdown
Member Author

Superseded by consolidated PR #3040. No commits were dropped or rewritten: #3040 now contains this exact linear commit as part of #3021#3040. Closing only the redundant draft PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant