Skip to content

simplify session dependent tasks (#91729)#93227

Merged
lukesandberg merged 1 commit into
canaryfrom
re_apply_session_dependent_tasks_v2
May 13, 2026
Merged

simplify session dependent tasks (#91729)#93227
lukesandberg merged 1 commit into
canaryfrom
re_apply_session_dependent_tasks_v2

Conversation

@lukesandberg
Copy link
Copy Markdown
Contributor

@lukesandberg lukesandberg commented Apr 24, 2026

Summary

This is a re-application of #91729 without the TTL support (fetch Cache-Control and TransientState changes are excluded).

Make session_dependent a function attribute

Previously, tasks called mark_session_dependent() at runtime to flag themselves. This PR makes it a compile-time #[turbo_tasks::function(session_dependent)] attribute instead. Benefits:

  • Enables eager aggregation number selection: Session-dependent tasks change on every session restore, behaving like dirty leaf nodes. By knowing at task creation time (not mid-execution) that a task is session-dependent, the backend can assign a high initial aggregation number, preventing long dirty-propagation chains through intermediate aggregated nodes.
  • Simpler API: No runtime mark_session_dependent() call needed — the attribute is declarative and statically checked.
  • Removes mark_session_dependent(), mark_own_task_as_session_dependent(), and the session_dependent field from InProgressStateInner. The backend now reads is_session_dependent directly from the NativeFunction metadata via TaskGuard::is_session_dependent().

Test Plan

  • Existing tests continue to pass
  • cargo check -p turbo-tasks -p turbo-tasks-backend -p turbo-tasks-fetch

Why was #91729 reverted?

The original attempt seemed to be triggering OOMs on front. Through debugging there were no obvious ways in which it was tied to this change but rather due to invalidation races which motivated changes like #92389 to remove races from restore paths and #92814 which eliminated some expensive errors from eventually consistent executions.

Copy link
Copy Markdown
Contributor Author

lukesandberg commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

Doc comment references removed function turbo_tasks::mark_session_dependent, creating a broken rustdoc link.

Fix on Vercel

@lukesandberg lukesandberg force-pushed the re_apply_session_dependent_tasks_v2 branch 3 times, most recently from 4d4ba2e to 8dfbea9 Compare April 25, 2026 00:27
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 25, 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) 812ms 811ms █████
Cold (Ready in log) 778ms 777ms ▆▅▆█▅
Cold (First Request) 1.193s 1.196s ▁▃▅█▁
Warm (Listen) 812ms 812ms ▃▇▁▅▅
Warm (Ready in log) 776ms 777ms ▂▂▃▅▁
Warm (First Request) 577ms 576ms ▃▂▃▅▁
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 811ms 810ms ▆█▃▃▃
Cold (Ready in log) 787ms 790ms █▃▁▇▇
Cold (First Request) 3.232s 3.273s █▂▁▅▆
Warm (Listen) 810ms 810ms ▅▅▃▃▅
Warm (Ready in log) 788ms 789ms ▆▂▁▇▆
Warm (First Request) 3.288s 3.296s ▇▂▁▅▇

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 4.700s 4.702s ▂▄▄▃▃
Cached Build 4.666s 4.709s ▁▃▂▅▁
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 23.604s 23.940s █▇▃▇▆
Cached Build 23.747s 23.914s ██▁▆█
node_modules Size 506 MB 506 MB █████
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles
Canary PR Change
04hm05ar7kldw.js gzip 5.73 kB N/A -
0cz1d0mv5g_q7.js gzip 39.4 kB 39.4 kB
0dvitrl5zg37g.js gzip 8.82 kB N/A -
0sf7ysou-72zd.js gzip 8.71 kB N/A -
13hp7a8nabpph.js gzip 160 B N/A -
157abun3hwc_s.js gzip 10.3 kB N/A -
189drjxvd_ara.js gzip 151 B N/A -
1elt1qium-r2m.css gzip 115 B 115 B
1emtlsxh55saq.js gzip 156 B N/A -
1jj68jv9537mc.js gzip 13.8 kB N/A -
1jpaub6y8xlfr.js gzip 2.3 kB N/A -
1ot0mvscrc_uf.js gzip 233 B N/A -
1u4z-8vtf7423.js gzip 156 B N/A -
1v1_5f5o4okrx.js gzip 156 B N/A -
2_m3xv2uq3sjc.js gzip 1.46 kB N/A -
2-zwnlw5uui4h.js gzip 154 B N/A -
24y34mwgrkqp4.js gzip 8.78 kB N/A -
2c-fd4y1zozz8.js gzip 8.79 kB N/A -
2d7416h_xd36x.js gzip 8.71 kB N/A -
2extn3odmmem_.js gzip 12.9 kB N/A -
2fyhyy7niw9r6.js gzip 7.61 kB N/A -
2lyuhit6rn8fy.js gzip 9.44 kB N/A -
2pcgd_aqiiat5.js gzip 70.8 kB N/A -
2q0gr8wfr3jwl.js gzip 8.77 kB N/A -
2q224pr6t6lxs.js gzip 150 B N/A -
2t9e75oz6r0zp.js gzip 8.76 kB N/A -
2uku_olcn15b7.js gzip 8.79 kB N/A -
30r8mm-46bdqy.js gzip 220 B 220 B
33ltxwdtt291k.js gzip 160 B N/A -
3830nv998xh4k.js gzip 156 B N/A -
3dyld9d_xsqrn.js gzip 49.9 kB N/A -
3ej3-jpeu72k-.js gzip 154 B N/A -
3inab2jybr4k9.js gzip 450 B N/A -
3jkm5tdjvaf_q.js gzip 13.1 kB N/A -
3mt67agm5wp40.js gzip 10.6 kB N/A -
3rssl3skxqw0e.js gzip 65.6 kB N/A -
3saabek4kohwi.js gzip 10 kB N/A -
3yw6jm3cxfyra.js gzip 165 B N/A -
3z6o-0747nqms.js gzip 157 B N/A -
4189xmby9yu1p.js gzip 13.6 kB N/A -
42suxw9pkvyvg.js gzip 154 B N/A -
turbopack-0j..iuqy.js gzip 4.2 kB N/A -
turbopack-0m..8dfb.js gzip 4.2 kB N/A -
turbopack-1d.._m4a.js gzip 4.21 kB N/A -
turbopack-1d..xt5-.js gzip 4.2 kB N/A -
turbopack-1l..j_bn.js gzip 4.2 kB N/A -
turbopack-1q..nh1y.js gzip 4.2 kB N/A -
turbopack-1s..3v6b.js gzip 4.2 kB N/A -
turbopack-1v..9m4a.js gzip 4.2 kB N/A -
turbopack-1y..ywtc.js gzip 4.2 kB N/A -
turbopack-21..k7x-.js gzip 4.18 kB N/A -
turbopack-2j..2j5y.js gzip 4.2 kB N/A -
turbopack-2u..5c5s.js gzip 4.2 kB N/A -
turbopack-36..fk6e.js gzip 4.2 kB N/A -
turbopack-43..ebbm.js gzip 4.19 kB N/A -
0_i7nqgx23st7.js gzip N/A 10 kB -
04ecz5id4y-83.js gzip N/A 49.9 kB -
05e40c15cx1dd.js gzip N/A 7.61 kB -
06gjxxymo1fyh.js gzip N/A 155 B -
06puhytyxk31p.js gzip N/A 8.82 kB -
0ku8f6jqu2bqf.js gzip N/A 70.8 kB -
0m34gln_kt4fg.js gzip N/A 5.73 kB -
0p93wfky2uu5w.js gzip N/A 157 B -
134_hu95tlizi.js gzip N/A 155 B -
1g3q1ww01thnl.js gzip N/A 2.3 kB -
1hraqxuiymq6v.js gzip N/A 8.79 kB -
1l9un1sl77287.js gzip N/A 1.46 kB -
1tr4rv_xncc5l.js gzip N/A 157 B -
21-eavqb1k_36.js gzip N/A 13.9 kB -
2147zgtf14z-q.js gzip N/A 234 B -
21njcykb-zh7o.js gzip N/A 161 B -
23bz3xsg-5-1s.js gzip N/A 8.71 kB -
24cgay5i_hxbo.js gzip N/A 154 B -
27441mytv7pbm.js gzip N/A 9.43 kB -
2cjkwjgm1zcfs.js gzip N/A 8.71 kB -
2qpr2lso48yql.js gzip N/A 156 B -
2rarx_dw0y63l.js gzip N/A 153 B -
2scd8zaoyb8md.js gzip N/A 8.79 kB -
2st_qs6p_9us0.js gzip N/A 13.1 kB -
2zo2exm1d8qj1.js gzip N/A 13.6 kB -
312mq_8mkriok.js gzip N/A 156 B -
31jz96iin42s5.js gzip N/A 156 B -
3ehsq7o481snb.js gzip N/A 65.6 kB -
3hn75zuxly9az.js gzip N/A 10.3 kB -
3hqh7m128tvsn.js gzip N/A 8.77 kB -
3hqti_t-zy1x4.js gzip N/A 449 B -
3mnawenie1flm.js gzip N/A 8.76 kB -
3ubsozlu6zs38.js gzip N/A 10.6 kB -
3v_zh_vwexa4n.js gzip N/A 151 B -
41mf-x3mmsxae.js gzip N/A 12.9 kB -
42e_gn0ci04-o.js gzip N/A 168 B -
436k78wa2qok1.js gzip N/A 159 B -
43iwfqjnx1cy_.js gzip N/A 8.78 kB -
turbopack-04..88kd.js gzip N/A 4.2 kB -
turbopack-0c..f337.js gzip N/A 4.2 kB -
turbopack-0d..fsbc.js gzip N/A 4.2 kB -
turbopack-0f..dp0v.js gzip N/A 4.2 kB -
turbopack-0i..b2pl.js gzip N/A 4.2 kB -
turbopack-0q..tpb_.js gzip N/A 4.2 kB -
turbopack-0y..xt_6.js gzip N/A 4.2 kB -
turbopack-13..j7p5.js gzip N/A 4.2 kB -
turbopack-1g..yg50.js gzip N/A 4.2 kB -
turbopack-2o..y62b.js gzip N/A 4.2 kB -
turbopack-2v..k3md.js gzip N/A 4.2 kB -
turbopack-3c..bxd7.js gzip N/A 4.21 kB -
turbopack-3r..tjlu.js gzip N/A 4.18 kB -
turbopack-3w..fd4k.js gzip N/A 4.2 kB -
Total 468 kB 469 kB ⚠️ +88 B

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 717 B 715 B
Total 717 B 715 B ✅ -2 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 432 B 432 B
Total 432 B 432 B

📦 Webpack

Client

Main Bundles
Canary PR Change
2258-HASH.js gzip 61.4 kB N/A -
2266-HASH.js gzip 4.69 kB N/A -
3317.HASH.js gzip 169 B N/A -
4866-HASH.js gzip 5.64 kB N/A -
9e302639-HASH.js gzip 62.7 kB N/A -
framework-HASH.js gzip 59.5 kB 59.5 kB
main-app-HASH.js gzip 254 B 252 B
main-HASH.js gzip 39.9 kB 39.9 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
175fd0fd-HASH.js gzip N/A 62.7 kB -
2596-HASH.js gzip N/A 5.63 kB -
34-HASH.js gzip N/A 61.3 kB -
5691.HASH.js gzip N/A 169 B -
9156-HASH.js gzip N/A 4.68 kB -
Total 236 kB 236 kB ✅ -102 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 193 B 193 B
_error-HASH.js gzip 181 B 182 B
css-HASH.js gzip 334 B 332 B
dynamic-HASH.js gzip 1.79 kB 1.81 kB
edge-ssr-HASH.js gzip 255 B 255 B
head-HASH.js gzip 351 B 348 B
hooks-HASH.js gzip 385 B 384 B
image-HASH.js gzip 580 B 580 B
index-HASH.js gzip 257 B 259 B
link-HASH.js gzip 2.51 kB 2.52 kB
routerDirect..HASH.js gzip 318 B 319 B
script-HASH.js gzip 387 B 386 B
withRouter-HASH.js gzip 316 B 316 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.97 kB 7.99 kB ⚠️ +19 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 126 kB 126 kB
page.js gzip 275 kB 270 kB 🟢 5.3 kB (-2%)
Total 401 kB 396 kB ✅ -5.52 kB
Middleware
Canary PR Change
middleware-b..fest.js gzip 617 B 614 B
middleware-r..fest.js gzip 155 B 155 B
middleware.js gzip 44.4 kB 44.8 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 46 kB 46.4 kB ⚠️ +419 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 719 B 717 B
Total 719 B 717 B ✅ -2 B
Build Cache
Canary PR Change
0.pack gzip 4.47 MB 4.47 MB
index.pack gzip 115 kB 116 kB
index.pack.old gzip 113 kB 115 kB 🔴 +2.11 kB (+2%)
Total 4.7 MB 4.7 MB ✅ -1.48 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 350 kB 350 kB
app-page-exp..prod.js gzip 194 kB 194 kB
app-page-tur...dev.js gzip 349 kB 349 kB
app-page-tur..prod.js gzip 194 kB 194 kB
app-page-tur...dev.js gzip 346 kB 346 kB
app-page-tur..prod.js gzip 192 kB 192 kB
app-page.run...dev.js gzip 346 kB 346 kB
app-page.run..prod.js gzip 192 kB 192 kB
app-route-ex...dev.js gzip 77.5 kB 77.5 kB
app-route-ex..prod.js gzip 52.9 kB 52.9 kB
app-route-tu...dev.js gzip 77.6 kB 77.6 kB
app-route-tu..prod.js gzip 52.9 kB 52.9 kB
app-route-tu...dev.js gzip 77.2 kB 77.2 kB
app-route-tu..prod.js gzip 52.7 kB 52.7 kB
app-route.ru...dev.js gzip 77.1 kB 77.1 kB
app-route.ru..prod.js gzip 52.7 kB 52.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 44.3 kB 44.3 kB
pages-api-tu..prod.js gzip 33.8 kB 33.8 kB
pages-api.ru...dev.js gzip 44.3 kB 44.3 kB
pages-api.ru..prod.js gzip 33.7 kB 33.7 kB
pages-turbo....dev.js gzip 53.7 kB 53.7 kB
pages-turbo...prod.js gzip 39.4 kB 39.4 kB
pages.runtim...dev.js gzip 53.6 kB 53.6 kB
pages.runtim..prod.js gzip 39.4 kB 39.4 kB
server.runti..prod.js gzip 63.1 kB 63.1 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 68 kB 68 kB
use-cache-pr...dev.js gzip 68 kB 68 kB
Total 3.37 MB 3.37 MB
📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/13be82fe59f0705d933f919756a50d7baa6efa57/next

Commit: 13be82f

@lukesandberg lukesandberg force-pushed the re_apply_session_dependent_tasks_v2 branch from 8dfbea9 to af1f451 Compare April 25, 2026 01:15
@lukesandberg lukesandberg marked this pull request as ready for review April 25, 2026 01:19
@lukesandberg lukesandberg requested a review from a team April 25, 2026 01:20
@lukesandberg lukesandberg force-pushed the re_apply_session_dependent_tasks_v2 branch from af1f451 to c326a28 Compare May 2, 2026 05:54
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

Tests Passed

Commit: 13be82f

@lukesandberg lukesandberg force-pushed the re_apply_session_dependent_tasks_v2 branch from c326a28 to 13be82f Compare May 13, 2026 07:19
@lukesandberg lukesandberg enabled auto-merge (squash) May 13, 2026 07:20
@lukesandberg lukesandberg merged commit ee6cf0c into canary May 13, 2026
299 of 302 checks passed
@lukesandberg lukesandberg deleted the re_apply_session_dependent_tasks_v2 branch May 13, 2026 14:25
lukesandberg added a commit that referenced this pull request May 14, 2026
…#91729) (#93228)

## Summary

This is a re-application of the HTTP fetch part of #91729. Stacked on
#93227.

### Fix fetch to respect HTTP `Cache-Control` headers

Previously, `fetch` results were cached indefinitely, meaning results
would never be refreshed (unless the cache was invalidated). Now they
are `session_dependent` with a TTL to ensure we respect HTTP cache
settings (e.g. Google Fonts with `max-age=86400`).

New two-task pattern:
- **`fetch_inner`** (NOT `session_dependent`): Performs the HTTP
request, grabs an `Invalidator` for itself, and returns the response +
invalidator + absolute deadline. Cached across sessions.
- **`fetch`** (`network`, `session_dependent`): Reads the cached
`fetch_inner` result and spawns a timer to invalidate when the TTL
expires.

On warm cache restore, `fetch` re-executes (session-dependent), reads
the persisted deadline from `fetch_inner`'s cached result, computes
remaining TTL, and spawns a timer — no HTTP request unless the TTL has
already expired. Mid-session, the timer fires and triggers a re-fetch.

Error handling: On fetch failure, `fetch_inner` takes a dependency on
`Completion::session_dependent()` so transient errors (network down, DNS
failure) are retried on the next session without busy-looping.

## Test Plan

3 new integration tests in `turbo-tasks-fetch/tests/fetch.rs`:
- `ttl_invalidates_within_session` — mock server returns `max-age=1`,
body changes, verifies re-fetch after TTL
- `ttl_invalidates_on_session_restore` — fetches with TTL, stops TT,
waits for expiry, warm restores with new TT, verifies re-fetch
- `errors_retried_on_session_restore` — server returns 500, stops TT,
fixes server, warm restores, verifies success
- Existing 6 fetch tests continue to pass



<!-- NEXT_JS_LLM_PR -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants