Skip to content

re-introduce partial fallback -> route upgrading#89063

Merged
ztanner merged 2 commits intocanaryfrom
01-26-re-introduce_partial_fallback_-_route_upgrading
Mar 6, 2026
Merged

re-introduce partial fallback -> route upgrading#89063
ztanner merged 2 commits intocanaryfrom
01-26-re-introduce_partial_fallback_-_route_upgrading

Conversation

@ztanner
Copy link
Member

@ztanner ztanner commented Jan 26, 2026

In #69282, we landed support for Partial Fallback Prerendering. The intention behind this feature was to be able to upgrade from a partial fallback (essentially the UI produced when await params is dynamic, ie the param was not part of generateStaticParams at build time) to a route shell (when the param values are filled in, and thus we can prerender more of the page).

It was reverted in #79258 because we didn't add first-class support to this in the build output API and the necessary infrastructure changes to perform similar behavior that this PR does to trigger a background revalidation with params filled in.

This re-lands the feature in Next.js now that upstream support landed in our public adapter/CLI (vercel/vercel#14703, vercel/vercel#15338, nextjs/adapter-vercel#39, and Vercel infra changes which are rolling out)

Copy link
Member Author

ztanner commented Jan 26, 2026

@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Jan 26, 2026

Tests Passed

@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Jan 26, 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) 456ms 456ms ▁▁▁▁▁
Cold (Ready in log) 436ms 437ms ▁▁▁▁▁
Cold (First Request) 1.274s 1.250s ▂▂▁▁▂
Warm (Listen) 456ms 457ms ▁▁▁▁▁
Warm (Ready in log) 442ms 442ms ▁▁▁▁▁
Warm (First Request) 350ms 349ms ▁▁▁▁▁
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 507ms 507ms ▁▁▁▁▁
Cold (Ready in log) 499ms 503ms ▆▆▅▅▁
Cold (First Request) 2.283s 2.278s ▄▃▃▇▁
Warm (Listen) 507ms 508ms ▁▁▁▁▁
Warm (Ready in log) 501ms 497ms ▅▄▅▅▁
Warm (First Request) 2.305s 2.287s ▄▄▄▇▁

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 3.853s 3.803s ▁▁▁▁▁
Cached Build 3.897s 3.839s ▁▁▁▁▁
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 16.566s 16.592s ▁▁▂▅▁
Cached Build 16.651s 16.674s ▁▁▁▅▁
node_modules Size 477 MB 477 MB ▁▁▁▁▁
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles: **402 kB** → **402 kB** ⚠️ +31 B

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

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 766 B 767 B
Total 766 B 767 B ⚠️ +1 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 446 B 450 B
Total 446 B 450 B ⚠️ +4 B

📦 Webpack

Client

Main Bundles
Canary PR Change
5528-HASH.js gzip 5.54 kB N/A -
6280-HASH.js gzip 59.4 kB N/A -
6335.HASH.js gzip 169 B N/A -
912-HASH.js gzip 4.59 kB N/A -
e8aec2e4-HASH.js gzip 62.6 kB N/A -
framework-HASH.js gzip 59.7 kB 59.7 kB
main-app-HASH.js gzip 256 B 255 B
main-HASH.js gzip 39.1 kB 39.1 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
262-HASH.js gzip N/A 4.59 kB -
2889.HASH.js gzip N/A 169 B -
5602-HASH.js gzip N/A 5.55 kB -
6948ada0-HASH.js gzip N/A 62.6 kB -
9544-HASH.js gzip N/A 60.2 kB -
Total 233 kB 234 kB ⚠️ +734 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.51 kB 2.51 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.98 kB 7.98 kB ✅ -1 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 125 kB 125 kB
page.js gzip 256 kB 256 kB
Total 380 kB 381 kB ⚠️ +1.05 kB
Middleware
Canary PR Change
middleware-b..fest.js gzip 619 B 615 B
middleware-r..fest.js gzip 156 B 155 B
middleware.js gzip 43.8 kB 43.7 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 45.4 kB 45.3 kB ✅ -88 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 715 B 718 B
Total 715 B 718 B ⚠️ +3 B
Build Cache
Canary PR Change
0.pack gzip 4.06 MB 4.08 MB 🔴 +14.1 kB (+0%)
index.pack gzip 103 kB 103 kB
index.pack.old gzip 103 kB 104 kB
Total 4.27 MB 4.29 MB ⚠️ +15 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 322 kB 322 kB
app-page-exp..prod.js gzip 171 kB 171 kB
app-page-tur...dev.js gzip 322 kB 322 kB
app-page-tur..prod.js gzip 171 kB 171 kB
app-page-tur...dev.js gzip 318 kB 318 kB
app-page-tur..prod.js gzip 169 kB 169 kB
app-page.run...dev.js gzip 319 kB 319 kB
app-page.run..prod.js gzip 169 kB 169 kB
app-route-ex...dev.js gzip 70.9 kB 70.9 kB
app-route-ex..prod.js gzip 49.3 kB 49.3 kB
app-route-tu...dev.js gzip 70.9 kB 70.9 kB
app-route-tu..prod.js gzip 49.3 kB 49.3 kB
app-route-tu...dev.js gzip 70.5 kB 70.5 kB
app-route-tu..prod.js gzip 49 kB 49.1 kB
app-route.ru...dev.js gzip 70.4 kB 70.5 kB
app-route.ru..prod.js gzip 49 kB 49 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.3 kB
pages-api-tu..prod.js gzip 32.9 kB 32.9 kB
pages-api.ru...dev.js gzip 43.2 kB 43.2 kB
pages-api.ru..prod.js gzip 32.9 kB 32.9 kB
pages-turbo....dev.js gzip 52.6 kB 52.6 kB
pages-turbo...prod.js gzip 38.5 kB 38.5 kB
pages.runtim...dev.js gzip 52.6 kB 52.6 kB
pages.runtim..prod.js gzip 38.5 kB 38.5 kB
server.runti..prod.js gzip 62 kB 62 kB
Total 2.84 MB 2.84 MB ⚠️ +431 B
📝 Changed Files (25 files)

Files with changes:

  • app-page-exp..ntime.dev.js
  • app-page-exp..time.prod.js
  • app-page-tur..ntime.dev.js
  • app-page-tur..time.prod.js
  • app-page-tur..ntime.dev.js
  • app-page-tur..time.prod.js
  • app-page.runtime.dev.js
  • app-page.runtime.prod.js
  • app-route-ex..ntime.dev.js
  • app-route-ex..time.prod.js
  • app-route-tu..ntime.dev.js
  • app-route-tu..time.prod.js
  • app-route-tu..ntime.dev.js
  • app-route-tu..time.prod.js
  • app-route.runtime.dev.js
  • app-route.ru..time.prod.js
  • pages-api-tu..ntime.dev.js
  • pages-api-tu..time.prod.js
  • pages-api.runtime.dev.js
  • pages-api.ru..time.prod.js
  • ... and 5 more
View diffs
app-page-exp..ntime.dev.js
failed to diff
app-page-exp..time.prod.js

Diff too large to display

app-page-tur..ntime.dev.js
failed to diff
app-page-tur..time.prod.js

Diff too large to display

app-page-tur..ntime.dev.js
failed to diff
app-page-tur..time.prod.js

Diff too large to display

app-page.runtime.dev.js
failed to diff
app-page.runtime.prod.js

Diff too large to display

app-route-ex..ntime.dev.js

Diff too large to display

app-route-ex..time.prod.js

Diff too large to display

app-route-tu..ntime.dev.js

Diff too large to display

app-route-tu..time.prod.js

Diff too large to display

app-route-tu..ntime.dev.js

Diff too large to display

app-route-tu..time.prod.js

Diff too large to display

app-route.runtime.dev.js

Diff too large to display

app-route.ru..time.prod.js

Diff too large to display

pages-api-tu..ntime.dev.js

Diff too large to display

pages-api-tu..time.prod.js

Diff too large to display

pages-api.runtime.dev.js

Diff too large to display

pages-api.ru..time.prod.js

Diff too large to display

pages-turbo...ntime.dev.js

Diff too large to display

pages-turbo...time.prod.js

Diff too large to display

pages.runtime.dev.js

Diff too large to display

pages.runtime.prod.js

Diff too large to display

server.runtime.prod.js

Diff too large to display

📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/e7da475d6553d348bac8d450c92f8d1c969569a3/next

@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch 3 times, most recently from d75a8eb to 69eae77 Compare January 30, 2026 23:17
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 69eae77 to 3c112e2 Compare February 23, 2026 23:03
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 3c112e2 to b849252 Compare February 25, 2026 19:25
ztanner added a commit to vercel/vercel that referenced this pull request Mar 2, 2026
This PR adds the `partialFallback` property onto the Prerender document.
This will signal different fallback semantics: namely, the expectation
with a partial fallback is that it will immediately kick off a
background revalidation to produce a more complete static document.

See vercel/next.js#89063 corresponding Next.js
changes.
@ztanner ztanner changed the base branch from canary to graphite-base/89063 March 4, 2026 20:10
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from b849252 to 22c0c6f Compare March 4, 2026 20:10
@ztanner ztanner changed the base branch from graphite-base/89063 to 02-23-partial_fallbacks_add_adapter_flag_tweak_allowquery March 4, 2026 20:11
@ztanner ztanner changed the base branch from 02-23-partial_fallbacks_add_adapter_flag_tweak_allowquery to graphite-base/89063 March 4, 2026 20:27
@ztanner ztanner force-pushed the graphite-base/89063 branch from 22e217d to 8bfc33f Compare March 4, 2026 20:27
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 22c0c6f to 219a7ff Compare March 4, 2026 20:27
@ztanner ztanner force-pushed the graphite-base/89063 branch from 8bfc33f to ed3bb76 Compare March 4, 2026 20:38
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 219a7ff to 0d04c66 Compare March 4, 2026 20:38
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 4, 2026

Merging this PR will not alter performance

✅ 17 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing 01-26-re-introduce_partial_fallback_-_route_upgrading (22c0c6f) with canary (8bd3a2a)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 graphite-base/89063 (8bd3a2a) during the generation of this report, so canary (8bd3a2a) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@ztanner ztanner force-pushed the graphite-base/89063 branch from ed3bb76 to 82ddf97 Compare March 4, 2026 22:56
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 0d04c66 to 52bac7b Compare March 4, 2026 22:56
@ztanner ztanner changed the base branch from graphite-base/89063 to ztanner/partial-fallback-allowquery March 4, 2026 22:57
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 52bac7b to 9972012 Compare March 5, 2026 20:21
@ztanner ztanner force-pushed the ztanner/partial-fallback-allowquery branch from 82ddf97 to 05758b2 Compare March 5, 2026 20:21
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 9972012 to 8bf4590 Compare March 5, 2026 21:14
@ztanner ztanner marked this pull request as ready for review March 5, 2026 21:32
@ztanner ztanner requested review from gnoff and ijjk March 5, 2026 21:32
// request itself.
!isPrefetchRSCRequest
) {
scheduleOnNextTick(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

feels like responseCache shoud own the concept of background revalidating. or we should abstract this into a shared helper.

Copy link
Member Author

ztanner commented Mar 6, 2026

Merge activity

  • Mar 6, 4:16 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Mar 6, 4:18 PM UTC: Graphite rebased this pull request as part of a merge.
  • Mar 6, 4:39 PM UTC: Graphite couldn't merge this PR because it was not satisfying all requirements (Failed CI: 'thank you, next', 'test integration windows / build', 'test prod (7/10) / build').

@ztanner ztanner changed the base branch from ztanner/partial-fallback-allowquery to graphite-base/89063 March 6, 2026 16:16
@ztanner ztanner changed the base branch from graphite-base/89063 to canary March 6, 2026 16:16
@ztanner ztanner force-pushed the 01-26-re-introduce_partial_fallback_-_route_upgrading branch from 8bf4590 to e7da475 Compare March 6, 2026 16:17
@ztanner ztanner merged commit af48a18 into canary Mar 6, 2026
280 of 283 checks passed
@ztanner ztanner deleted the 01-26-re-introduce_partial_fallback_-_route_upgrading branch March 6, 2026 16:53
sokra pushed a commit that referenced this pull request Mar 6, 2026
In #69282, we landed support for
Partial Fallback Prerendering. The intention behind this feature was to
be able to upgrade from a partial fallback (essentially the UI produced
when `await params` is dynamic, ie the param was not part of
`generateStaticParams` at build time) to a route shell (when the param
values are filled in, and thus we can prerender more of the page).

It was reverted in #79258 because
we didn't add first-class support to this in the build output API and
the necessary infrastructure changes to perform similar behavior that
this PR does to trigger a background revalidation with params filled in.

This re-lands the feature in Next.js now that upstream support landed
(vercel/vercel#14703,
vercel/vercel#15338, and Vercel infra changes
which are rolling out)
ztanner added a commit that referenced this pull request Mar 9, 2026
This puts the partial fallback upgrading feature introduced in
#89063 behind a flag to make it
easier to test the rollout/eventual stabilization in isolation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants