Skip to content

Handle Pages data route skew with deployment id header, take 2#89325

Merged
mischnic merged 3 commits intocanaryfrom
mischnic/reapply-pages-buildid
Feb 4, 2026
Merged

Handle Pages data route skew with deployment id header, take 2#89325
mischnic merged 3 commits intocanaryfrom
mischnic/reapply-pages-buildid

Conversation

@mischnic
Copy link
Member

@mischnic mischnic commented Jan 30, 2026

Reapply #88959
Revert #89323

Closes PACK-6537
Closes PACK-6756

  • Deployment skew (forcing a MPA nav instead of a SPA nav if a deployment happened inbetween) is handled by comparing a header on the client side.
  • Then, when a deployment id is available, make the build id a constant
    • Particularly, this makes the rollout of this much easier as the data route paths stay the same (both in Next.js itself as well as in the builder)

If you use output:export and set config.deploymentId (i.e. enable skew protection) you are still expected to set these headers.

Copy link
Member Author

mischnic commented Jan 30, 2026

@mischnic mischnic changed the title Reapply "Replace build id in Pages data routes with deployment id (#88959)" (#89323) Replace build id in Pages data routes with deployment id, take 2 Jan 30, 2026
@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Jan 30, 2026

Stats from current PR

✅ No significant changes detected

📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 455ms 454ms ▁▁▁▁▁
Cold (Ready in log) 438ms 437ms ▂▂▂▁▁
Cold (First Request) 1.147s 1.198s ▅▅▄▁▁
Warm (Listen) 456ms 457ms ▁▁▁▁▁
Warm (Ready in log) 443ms 446ms ▁▁▁▁▁
Warm (First Request) 339ms 343ms ▁▂▂▁▂
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 456ms 455ms ▁▁▁▁█
Cold (Ready in log) 449ms 450ms ▄▆▅▆█
Cold (First Request) 1.931s 1.922s ▃▆▄▆█
Warm (Listen) 456ms 456ms ▁▁▁▁█
Warm (Ready in log) 450ms 450ms ▅▅▅▆█
Warm (First Request) 1.938s 1.918s ▃▄▃▅█

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 3.921s 3.961s ▁▁▁▃▂
Cached Build 3.968s 4.011s ▁▁▁▃▂
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 14.679s 14.657s ▁▃▁▄█
Cached Build 14.694s 14.665s ▁▃▁▄█
node_modules Size 464 MB 465 MB ▁▁▁▁▁
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles: **437 kB** → **437 kB** ⚠️ +75 B

81 files with content-based hashes (individual files not comparable between builds)

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 770 B 766 B
Total 770 B 766 B ✅ -4 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 450 B 450 B
Total 450 B 450 B

📦 Webpack

Client

Main Bundles
Canary PR Change
5528-HASH.js gzip 5.47 kB N/A -
6280-HASH.js gzip 56.8 kB N/A -
6335.HASH.js gzip 169 B N/A -
912-HASH.js gzip 4.53 kB N/A -
e8aec2e4-HASH.js gzip 62.5 kB N/A -
framework-HASH.js gzip 59.7 kB 59.7 kB
main-app-HASH.js gzip 256 B 254 B
main-HASH.js gzip 39 kB 39.1 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
262-HASH.js gzip N/A 4.52 kB -
2889.HASH.js gzip N/A 169 B -
5602-HASH.js gzip N/A 5.48 kB -
6948ada0-HASH.js gzip N/A 62.5 kB -
9544-HASH.js gzip N/A 57.4 kB -
Total 230 kB 231 kB ⚠️ +661 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 194 B 194 B
_error-HASH.js gzip 183 B 180 B 🟢 3 B (-2%)
css-HASH.js gzip 331 B 330 B
dynamic-HASH.js gzip 1.81 kB 1.81 kB
edge-ssr-HASH.js gzip 256 B 256 B
head-HASH.js gzip 351 B 352 B
hooks-HASH.js gzip 384 B 383 B
image-HASH.js gzip 580 B 581 B
index-HASH.js gzip 260 B 260 B
link-HASH.js gzip 2.49 kB 2.49 kB
routerDirect..HASH.js gzip 320 B 319 B
script-HASH.js gzip 386 B 386 B
withRouter-HASH.js gzip 315 B 315 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.97 kB ✅ -1 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 126 kB 126 kB
page.js gzip 249 kB 249 kB
Total 375 kB 375 kB ⚠️ +113 B
Middleware
Canary PR Change
middleware-b..fest.js gzip 614 B 617 B
middleware-r..fest.js gzip 156 B 155 B
middleware.js gzip 33 kB 33 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 34.6 kB 34.6 kB ⚠️ +15 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 732 B 736 B
Total 732 B 736 B ⚠️ +4 B
Build Cache
Canary PR Change
0.pack gzip 3.81 MB 3.83 MB 🔴 +12.8 kB (+0%)
index.pack gzip 103 kB 103 kB
index.pack.old gzip 103 kB 103 kB
Total 4.02 MB 4.03 MB ⚠️ +13.4 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 312 kB 312 kB
app-page-exp..prod.js gzip 166 kB 166 kB
app-page-tur...dev.js gzip 311 kB 311 kB
app-page-tur..prod.js gzip 166 kB 166 kB
app-page-tur...dev.js gzip 308 kB 308 kB
app-page-tur..prod.js gzip 164 kB 164 kB
app-page.run...dev.js gzip 308 kB 308 kB
app-page.run..prod.js gzip 164 kB 164 kB
app-route-ex...dev.js gzip 70.4 kB 70.4 kB
app-route-ex..prod.js gzip 48.9 kB 48.9 kB
app-route-tu...dev.js gzip 70.4 kB 70.4 kB
app-route-tu..prod.js gzip 49 kB 49 kB
app-route-tu...dev.js gzip 70 kB 70 kB
app-route-tu..prod.js gzip 48.7 kB 48.7 kB
app-route.ru...dev.js gzip 70 kB 70 kB
app-route.ru..prod.js gzip 48.7 kB 48.7 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 43.2 kB 43.2 kB
pages-api-tu..prod.js gzip 32.9 kB 32.9 kB
pages-api.ru...dev.js gzip 43.1 kB 43.1 kB
pages-api.ru..prod.js gzip 32.8 kB 32.8 kB
pages-turbo....dev.js gzip 52.4 kB 52.4 kB
pages-turbo...prod.js gzip 39.4 kB 39.4 kB
pages.runtim...dev.js gzip 52.4 kB 52.4 kB
pages.runtim..prod.js gzip 39.3 kB 39.3 kB
server.runti..prod.js gzip 62.6 kB 62.6 kB
Total 2.78 MB 2.78 MB ✅ -1 B

@mischnic mischnic changed the base branch from canary to graphite-base/89325 February 3, 2026 10:51
@mischnic mischnic force-pushed the mischnic/reapply-pages-buildid branch from eaf3516 to b5483b8 Compare February 3, 2026 10:51
@mischnic mischnic changed the base branch from graphite-base/89325 to mischnic/flight-nav-requests-build-id February 3, 2026 10:51
@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Feb 3, 2026

Failing test suites

Commit: f7f0c15 | About building and testing Next.js

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 3, 2026

Merging this PR will degrade performance by 6.29%

❌ 3 regressed benchmarks
✅ 14 untouched benchmarks
⏩ 3 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation app-page-turbo.runtime.prod.js[full] 654.1 ms 698 ms -6.29%
Simulation app-page-turbo.runtime.prod.js[tracing] 571.2 ms 595.2 ms -4.04%
Simulation packages-bundle.js[full] 999.1 ms 1,052.2 ms -5.05%

Comparing mischnic/reapply-pages-buildid (b5483b8) with mischnic/flight-nav-requests-build-id (e0e23b6)2

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on mischnic/flight-nav-requests-build-id (b47ffc0) during the generation of this report, so a043432 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@mischnic mischnic force-pushed the mischnic/reapply-pages-buildid branch from b5483b8 to 842c8b0 Compare February 3, 2026 13:22
@mischnic mischnic changed the base branch from mischnic/flight-nav-requests-build-id to graphite-base/89325 February 3, 2026 13:23
@mischnic mischnic marked this pull request as ready for review February 3, 2026 13:25
@mischnic mischnic force-pushed the graphite-base/89325 branch from b47ffc0 to 0aac540 Compare February 3, 2026 13:29
@mischnic mischnic force-pushed the mischnic/reapply-pages-buildid branch from 842c8b0 to f7f0c15 Compare February 3, 2026 13:29
@mischnic mischnic changed the base branch from graphite-base/89325 to canary February 3, 2026 13:29
@mischnic mischnic requested a review from timneutkens February 3, 2026 15:04
@mischnic mischnic changed the title Replace build id in Pages data routes with deployment id, take 2 Replace build id in Pages data routes with deployment id header, take 2 Feb 4, 2026
@mischnic mischnic changed the title Replace build id in Pages data routes with deployment id header, take 2 Handle Pages data route skew with deployment id header, take 2 Feb 4, 2026
@mischnic mischnic merged commit 49e0a8a into canary Feb 4, 2026
227 of 230 checks passed
@mischnic mischnic deleted the mischnic/reapply-pages-buildid branch February 4, 2026 17:07
ijjk added a commit to vercel/vercel that referenced this pull request Feb 5, 2026
Since vercel/next.js#89325, the build id is
overridden to a hardcoded string `build-TfctsWXpff2fKS` when skew
protection is enabled.


https://github.com/vercel/next.js/blob/2521b8adc73957cf7dfc358bea3c461b04bcfa16/packages/next/src/build/index.ts#L906-L910

Update the e2e tests to use that instead.

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
bgub pushed a commit to bgub/next.js that referenced this pull request Feb 5, 2026
…l#89325)

Reapply vercel#88959
Revert vercel#89323


Closes PACK-6537
Closes PACK-6756

- Deployment skew (forcing a MPA nav instead of a SPA nav if a deployment happened inbetween) is handled by comparing a header on the client side.
    - The other case that used build ids was app router, which was changed to the same approach in vercel#88855
- Then, when a deployment id is available, make the build id a constant
	- Particularly, this makes the rollout of this much easier as the data route paths stay the same (both in Next.js itself as well as in the builder)


If you use `output:export` and set `config.deploymentId` (i.e. enable skew protection) you are still expected to set these headers.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants