[PR #1092] fix(cache): scope use cache keys by deployment id #1089

Open
opened 2026-05-06 13:11:55 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1092
Author: @NathanDrake2406
Created: 5/6/2026
Status: 🔄 Open

Base: mainHead: nathan/use-cache-deployment-id


📝 Commits (6)

  • 20cb09d fix(cache): scope use cache keys by deployment id
  • 60c8ebf fix(config): resolve deployment id for cache seeds
  • 518b83e refactor(cache): carry deployment id through request context
  • c3cf95c refactor(cache): reuse request context for deployment id
  • 1c7d459 Merge remote-tracking branch 'upstream/main' into nathan/use-cache-deployment-id
  • 6c3bd8c test(app-elements): expect artifact compatibility metadata

📊 Changes

12 files changed (+420 additions, -61 deletions)

View changed files

📝 packages/vinext/src/config/next-config.ts (+28 -0)
📝 packages/vinext/src/deploy.ts (+9 -0)
📝 packages/vinext/src/global.d.ts (+6 -0)
📝 packages/vinext/src/index.ts (+5 -0)
📝 packages/vinext/src/server/app-router-entry.ts (+97 -52)
📝 packages/vinext/src/server/app-rsc-handler.ts (+10 -0)
📝 packages/vinext/src/shims/cache-runtime.ts (+24 -9)
📝 packages/vinext/src/shims/unified-request-context.ts (+15 -0)
📝 tests/app-elements.test.ts (+1 -0)
📝 tests/deploy.test.ts (+11 -0)
📝 tests/next-config.test.ts (+57 -0)
📝 tests/shims.test.ts (+157 -0)

📄 Description

What this changes

Shared "use cache" entries now include a deployment-aware seed before falling back to the existing vinext build ID. This matches the upstream cache key precedence model for vinext's supported deployment ID sources while keeping Worker deployment identity request-scoped.

Why

Next.js changed use-cache-wrapper so cache keys use workStore.deploymentId || workStore.buildId. Without this, two deployments can share the same "use cache" entry when the build ID is stable or when a runtime deployment ID changes independently of the build fallback.

References:

Approach

  • Add a deployment-aware cache key seed in cache-runtime, with precedence: request-scoped deployment ID, explicit startup/test fallback, build-time resolved deployment ID, then vinext build ID.
  • Resolve next.config.js deploymentId before NEXT_DEPLOYMENT_ID, validate its string shape, and expose the resolved value through process.env.__VINEXT_DEPLOYMENT_ID.
  • Read Worker deployment identity from env.NEXT_DEPLOYMENT_ID or env.CF_VERSION_METADATA.id in the App Router Worker entry.
  • Use AsyncLocalStorage for the Worker deployment ID so concurrent requests cannot overwrite one another.
  • Generate a version_metadata binding in wrangler.jsonc so deployed Cloudflare Workers have CF_VERSION_METADATA.id available by default.

Validation

  • vp test run tests/shims.test.ts -t 'use cache'
  • vp test run tests/deploy.test.ts -t 'Wrangler Config Generation|generateAppRouterWorkerEntry'
  • vp test run tests/next-config.test.ts -t 'deploymentId|generateBuildId'
  • vp check packages/vinext/src/config/next-config.ts packages/vinext/src/shims/cache-runtime.ts packages/vinext/src/server/app-router-entry.ts packages/vinext/src/deploy.ts packages/vinext/src/index.ts packages/vinext/src/global.d.ts tests/shims.test.ts tests/deploy.test.ts tests/next-config.test.ts
  • Pre-commit hook ran vp check --fix and knip --no-progress

Risks / follow-ups

This PR scopes the App Router Worker entry and generated deploy config. Custom Worker entries that bypass vinext/server/app-router-entry still need to provide their own deployment context if they invoke lower-level internals directly.

★ Insight

  • Next.js seeds "use cache" with deployment identity before build identity because cacheHandlers can outlive a single build assumption.
  • Cloudflare version metadata is request-time Worker env state, so reading it at module registration would miss or race the real deployment value.
  • The fallback chain keeps existing build ID isolation intact for non-Cloudflare and local paths while adding stronger isolation for configured and Workers deployments.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1092 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 5/6/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `nathan/use-cache-deployment-id` --- ### 📝 Commits (6) - [`20cb09d`](https://github.com/cloudflare/vinext/commit/20cb09d52613de506b37cbb6da03d6da1892c2b7) fix(cache): scope use cache keys by deployment id - [`60c8ebf`](https://github.com/cloudflare/vinext/commit/60c8ebfe349bc1821065d5c770476f477c84931e) fix(config): resolve deployment id for cache seeds - [`518b83e`](https://github.com/cloudflare/vinext/commit/518b83e06da683dee04990a6c93b24bff2b9c594) refactor(cache): carry deployment id through request context - [`c3cf95c`](https://github.com/cloudflare/vinext/commit/c3cf95c5b3e04eb129a4772a1fbb103aff08d340) refactor(cache): reuse request context for deployment id - [`1c7d459`](https://github.com/cloudflare/vinext/commit/1c7d459017e000371a3c4008fb247f86f01dc223) Merge remote-tracking branch 'upstream/main' into nathan/use-cache-deployment-id - [`6c3bd8c`](https://github.com/cloudflare/vinext/commit/6c3bd8c4a6185741c4cb2c21bdc9842b6581b050) test(app-elements): expect artifact compatibility metadata ### 📊 Changes **12 files changed** (+420 additions, -61 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/config/next-config.ts` (+28 -0) 📝 `packages/vinext/src/deploy.ts` (+9 -0) 📝 `packages/vinext/src/global.d.ts` (+6 -0) 📝 `packages/vinext/src/index.ts` (+5 -0) 📝 `packages/vinext/src/server/app-router-entry.ts` (+97 -52) 📝 `packages/vinext/src/server/app-rsc-handler.ts` (+10 -0) 📝 `packages/vinext/src/shims/cache-runtime.ts` (+24 -9) 📝 `packages/vinext/src/shims/unified-request-context.ts` (+15 -0) 📝 `tests/app-elements.test.ts` (+1 -0) 📝 `tests/deploy.test.ts` (+11 -0) 📝 `tests/next-config.test.ts` (+57 -0) 📝 `tests/shims.test.ts` (+157 -0) </details> ### 📄 Description ## What this changes Shared `"use cache"` entries now include a deployment-aware seed before falling back to the existing vinext build ID. This matches the upstream cache key precedence model for vinext's supported deployment ID sources while keeping Worker deployment identity request-scoped. ## Why Next.js changed `use-cache-wrapper` so cache keys use `workStore.deploymentId || workStore.buildId`. Without this, two deployments can share the same `"use cache"` entry when the build ID is stable or when a runtime deployment ID changes independently of the build fallback. References: - Next.js source change: [packages/next/src/server/use-cache/use-cache-wrapper.ts](https://github.com/vercel/next.js/blob/07f76411b07de9417d4a6b816f3137cafe1045fc/packages/next/src/server/use-cache/use-cache-wrapper.ts#L1510-L1513) - Next.js work store plumbing: [packages/next/src/server/async-storage/work-store.ts](https://github.com/vercel/next.js/blob/07f76411b07de9417d4a6b816f3137cafe1045fc/packages/next/src/server/async-storage/work-store.ts#L63-L86) - Next.js regression test: [test/production/app-dir/use-cache-cross-deployment/use-cache-cross-deployment.test.ts](https://github.com/vercel/next.js/blob/07f76411b07de9417d4a6b816f3137cafe1045fc/test/production/app-dir/use-cache-cross-deployment/use-cache-cross-deployment.test.ts) - Next.js `deploymentId` config docs: [next.config.js deploymentId](https://nextjs.org/docs/app/api-reference/config/next-config-js/deploymentId) - Cloudflare version metadata binding: [Cloudflare Workers docs](https://developers.cloudflare.com/workers/runtime-apis/bindings/version-metadata/) - Tracks #1064 ## Approach - Add a deployment-aware cache key seed in `cache-runtime`, with precedence: request-scoped deployment ID, explicit startup/test fallback, build-time resolved deployment ID, then vinext build ID. - Resolve `next.config.js deploymentId` before `NEXT_DEPLOYMENT_ID`, validate its string shape, and expose the resolved value through `process.env.__VINEXT_DEPLOYMENT_ID`. - Read Worker deployment identity from `env.NEXT_DEPLOYMENT_ID` or `env.CF_VERSION_METADATA.id` in the App Router Worker entry. - Use AsyncLocalStorage for the Worker deployment ID so concurrent requests cannot overwrite one another. - Generate a `version_metadata` binding in `wrangler.jsonc` so deployed Cloudflare Workers have `CF_VERSION_METADATA.id` available by default. ## Validation - `vp test run tests/shims.test.ts -t 'use cache'` - `vp test run tests/deploy.test.ts -t 'Wrangler Config Generation|generateAppRouterWorkerEntry'` - `vp test run tests/next-config.test.ts -t 'deploymentId|generateBuildId'` - `vp check packages/vinext/src/config/next-config.ts packages/vinext/src/shims/cache-runtime.ts packages/vinext/src/server/app-router-entry.ts packages/vinext/src/deploy.ts packages/vinext/src/index.ts packages/vinext/src/global.d.ts tests/shims.test.ts tests/deploy.test.ts tests/next-config.test.ts` - Pre-commit hook ran `vp check --fix` and `knip --no-progress` ## Risks / follow-ups This PR scopes the App Router Worker entry and generated deploy config. Custom Worker entries that bypass `vinext/server/app-router-entry` still need to provide their own deployment context if they invoke lower-level internals directly. ★ Insight - Next.js seeds `"use cache"` with deployment identity before build identity because cacheHandlers can outlive a single build assumption. - Cloudflare version metadata is request-time Worker `env` state, so reading it at module registration would miss or race the real deployment value. - The fallback chain keeps existing build ID isolation intact for non-Cloudflare and local paths while adding stronger isolation for configured and Workers deployments. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1089
No description provided.