Skip to content

fix(cache): compare tag revalidation timestamps - #2916

Open
JamesbbBriz wants to merge 5 commits into
cloudflare:mainfrom
JamesbbBriz:codex/fix-cache-tag-revalidation-timestamps
Open

fix(cache): compare tag revalidation timestamps#2916
JamesbbBriz wants to merge 5 commits into
cloudflare:mainfrom
JamesbbBriz:codex/fix-cache-tag-revalidation-timestamps

Conversation

@JamesbbBriz

@JamesbbBriz JamesbbBriz commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • record request-local tag revalidations with timestamps instead of membership only
  • use the same high-resolution epoch clock for cache writes, invalidations, request starts, and fill starts
  • discard use cache, unstable_cache, and tagged fetch entries only when they predate the latest matching revalidation
  • suppress cache writes when a fill starts before a matching invalidation and completes afterward
  • securely forward revalidated-tag state across internal Server Action redirect dispatches without exposing protocol headers to application code
  • preserve comma-containing tags losslessly in a separate authenticated vinext JSON header while retaining the Next.js comma-delimited header for ordinary-tag rolling compatibility
  • import the timestamp helper directly from the lightweight cache-handler module on the common App Router path
  • preserve strict timestamp semantics across Memory, custom, and Cloudflare KV cache handlers

This follows the behavior introduced by vercel/next.js#96726 and commit 5da1c1ae03d2ee39c27a2d6d8807c573c46b37f9.

The separate JSON tag header is a deliberate vinext protocol extension: Next.js''s comma-delimited wire format cannot represent a legal tag containing a comma. New vinext peers prefer the authenticated JSON header; the standard header remains available to older peers for ordinary tags. Older peers cannot preserve comma-containing tags.

Closes #2819

Tests

  • Nine-file cache/ISR/action matrix passed: tests/shims.test.ts, tests/fetch-cache.test.ts, tests/unified-request-context.test.ts, tests/revalidated-tags.test.ts, tests/app-server-action-execution.test.ts, tests/app-rsc-handler.test.ts, tests/features.test.ts, tests/isr-cache.test.ts, and tests/kv-cache-handler.test.ts
  • vp check scoped to all changed product/test files (format, lint, and types clean)
  • git diff --check

Adversarial coverage includes repeated same-tag invalidation, fills straddling invalidation for all three public cache APIs, two-read Server Action dedupe before and after updateTag, custom-handler old/new timestamps, authenticated redirect forwarding, comma-containing and JSON-looking legacy tags, protocol-header filtering, soft/hard tag handler behavior, and Memory/KV strict timestamp boundaries.

@JamesbbBriz

Copy link
Copy Markdown
Contributor Author

/bigbonk

@pkg-pr-new

pkg-pr-new Bot commented Aug 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 36bbfdc

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 36bbfdc against base a3d1d1d using alternating same-runner rounds. Next.js was unchanged and skipped.

0 improved · 0 regressed · 6 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 135.4 KB 135.5 KB ⚫ +0.0%
Client entry size (gzip) vinext 122.8 KB 122.9 KB ⚫ +0.0%
Dev server cold start vinext 2.29 s 2.28 s ⚫ -0.3%
Production build time vinext 2.41 s 2.42 s ⚫ +0.1%
RSC entry closure size (gzip) vinext 114.6 KB 115.4 KB ⚫ +0.7%
Server bundle size (gzip) vinext 194.8 KB 195.9 KB ⚫ +0.5%

View detailed results and traces

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dab5b34173

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vinext/src/shims/cache-request-state.ts
@JamesbbBriz

Copy link
Copy Markdown
Contributor Author

/bigbonk

@JamesbbBriz

Copy link
Copy Markdown
Contributor Author

CI follow-up: fixed the integration failure by separating high-resolution mutation ordering (lastModified) from wall-clock TTL policy (writtenAt) in both Memory and KV handlers. Existing KV entries remain compatible via the lastModified fallback. Local verification: exact failed sequence 2/2, full features file 355/355, related 8-file matrix 1,903/1,903, scoped checks/diff-check, and independent Standards + blast-radius reviews pass. Waiting for CI; not requesting re-review yet.

@JamesbbBriz

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dbd28c1de2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/vinext/src/server/app-rsc-handler.ts Outdated
Comment thread packages/vinext/src/server/revalidated-tags.ts
@JamesbbBriz

JamesbbBriz commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

@james-elicx I think this is ready for another look now. I fixed the latest ISR review comments, and CI is green. Thanks!

@NathanDrake2406

Copy link
Copy Markdown
Contributor

I think we should generate the timestamp and pass it through the adapter, then have it persist and return that instead

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.

Cache: discard only 'use cache' entries that predate a tag revalidation (timestamp-compare, not tag membership)

2 participants