Skip to content

test: stabilize CPU simulation with isolated SSR workers and explicit V8 settings - #8248

Merged
Sheraff merged 10 commits into
mainfrom
codex/stabilize-cpu-simulation
Sep 5, 2026
Merged

test: stabilize CPU simulation with isolated SSR workers and explicit V8 settings#8248
Sheraff merged 10 commits into
mainfrom
codex/stabilize-cpu-simulation

Conversation

@Sheraff

@Sheraff Sheraff commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

🎯 Changes

CPU simulation scenario benchmarks produced multi-percent changes when rerunning identical code. This PR gives each SSR workload a fresh worker, makes Node 24 compiler/GC settings explicit, and replaces the streaming fixture's elapsed-time delay with counted task turns.

The final configuration adds four flags, down from five in the initial proposal. Post-isolation experiments allow removal of --no-incremental-marking-task. Eager baseline compilation and the 512 MiB heap budget remain: none of the tested default-heap configurations met the sub-1% repeatability target. The retained heap budget changes GC policy; repeatability does not establish representative production full-GC costs.

This builds on #7987. Production router code, workload names, navigation/request counts, concurrency, payload sizes and coverage are preserved. All measurements below are CPU simulation; memory results are excluded.

Observed impact

The selected configuration completed five independent Linux CI runs at one commit, each with all 132 fresh CPU measurements (660 measurements). Its largest observed spread was 0.593%.

Family Per run Original setup: 3 repeats Initial PR: 5 repeats Selected configuration: 5 repeats
client-nav original 3 0.246% 0.235% 0.117%
client-nav scenarios 36 1.800% 0.360% 0.465%
ssr original 3 0.549% 0.887% 0.460%
ssr scenarios 90 6.448% 0.420% 0.593%

Spread is 100 × (max simulated duration / min simulated duration − 1): the worst observed pair, not a confidence interval or a router speedup. Every comparison within a configuration uses one exact commit. Inherited, partial and memory results are excluded, and all workload-name sets match. The sub-1% criterion is the practical repeatability target used for these experiments, not a universal significance threshold. Not every individual benchmark's observed spread decreases.

Testing simpler configurations after worker isolation

Isolated-worker configuration Complete repeats Worst spread Benchmarks >1% Benchmarks >3%
Initial PR: five added flags 5 0.887% 0 0
Four flags: remove only the heap override 5 2.145% 2 0
Stock CodSpeed runtime: no added flags 3 14.272% 18 6
Two upstream Node fixes only 3 5.240% 3 1
Upstream fixes + heap budget 5 1.178% 1 0
Upstream fixes + eager baseline + heap budget (selected) 5 0.593% 0 0
Upstream fixes + eager baseline; stock heap and marking tasks 2 2.399% 2 0

These candidates differ only in the runtime helper and corresponding configuration tests. Worker isolation, benchmark code, builds, inputs, dependencies, pinned Node 24.8.0 and streaming fixtures remain the same. The last two candidates form a direct paired comparison: both keep the upstream Node fixes and eager baseline compilation, both use stock incremental-marking task behavior, and their runtime settings differ only in the heap budget.

Restoring stock incremental-marking task behavior passes when the heap budget and eager baseline compilation remain. Removing the heap budget in that same configuration fails the target. Removing eager baseline compilation with the heap retained also fails. These results justify removing the incremental-marking task override while retaining the two other project-specific controls in this PR.

A failing candidate can stop once an observed pair exceeds 1%, since further repetitions cannot reduce its max/min spread. The final default-heap candidate was stopped early on that basis; only its complete 132-measurement runs are included, and cancelled/partial results are excluded. Any retained configuration must complete all five repetitions.

The chosen configuration is the simplest stable one among the combinations tested; this is not an exhaustive search over every V8 flag combination. The stock-runtime result shows that file isolation alone does not establish repeatability.

Removing only the heap flag initially looked acceptable after two runs (0.980% worst spread), but the third exposed larger outliers. Across all five runs, Vue route headers reached 2.145% and Vue document middleware 2.109%; the other 130 benchmarks stayed below 0.80%. This is why the decisions use complete repeated suites rather than accepting the first promising pair.

Retained runtime controls

Flag Reason
--no-maglev The pinned CodSpeed integration supplies --no-opt, which disables TurboFan but leaves Maglev enabled on Node 24. A hot-loop reproduction confirmed this using the actual merged worker flags.
--no-minor-gc-task V8 renamed the old --no-scavenge-task flag, which the pinned integration omits on modern Node. This restores its intended allocation-driven minor-GC behavior.
--always-sparkplug Compiles baseline code on first use, avoiding later tier-up/batch-compilation thresholds. A worker probe confirmed baseline compilation for a once-called function. Removing only this flag from the selected four-flag configuration produced 1.178% spread in Vue head rendering across five runs.
--initial-old-space-size=512 Fixes the initial/minimum old-generation allocation budget. Removing only this flag from the selected configuration produced 2.399% spread after two complete runs. Its GC-policy tradeoff is described below.

The first two flags follow CodSpeed's upstream Node 24 fixes. The helper augments the integration's existing flags only when CodSpeed is active in CPU simulation or legacy instrumentation mode; its existing 4096 MiB maximum remains. These extra flags are absent from ordinary Vitest timing, walltime and memory execution.

Heap sizing and representativeness

The original --initial-old-space-size=512 did not make the first 512 MiB of cumulative allocation GC-free. It affected the old-generation budget. Minor collections still ran: a local SSR reproduction recorded 13 allocation-triggered scavenges inside the measured invocation, around 17–22 MiB of heap usage. CodSpeed's explicit pre-measurement full collection also still ran.

However, V8 uses the explicit initial size as a minimum allocation budget and can skip automatic full collections below it. It does not preallocate 512 MiB, but it can exclude full-GC work that a default-heap process would perform. Increased object retention can therefore have part of its eventual GC CPU cost omitted from these short simulations. See V8's initial/minimum heap configuration.

The final configuration retains this policy deliberately, based on the comparisons above. The result establishes repeatability, not representative production full-GC frequency or proof of sensitivity to every possible regression. The default-heap results remain in the PR so this tradeoff is visible when reviewing the change.

Worker and fixture changes

  • One SSR workload per file/worker: 93 SSR workloads previously shared 45 files. With explicit Vitest isolation and CodSpeed's forks pool, all 93 files receive fresh workers. The first case retains speed.bench.ts; 48 additional variants move to descriptive filenames. An AST comparison verifies all 93 names and complete bench() calls are unchanged. The 21 affected project TypeScript includes cover speed*.bench.ts. All 39 client benchmark files already contained a single workload. Vitest isolation.
  • Streaming scheduling: deferred payloads resolve after two Node task turns instead of a real 1 ms timer. This removes elapsed host time from their release schedule while preserving the initial loading render and full payloads, checked by existing HTML assertions. These benchmarks execute in Node and use setImmediate directly. This fixture change and file isolation apply whenever the CPU-suite fixtures run.
  • Shared configuration and checks: all 84 CPU project configurations use one helper. Nx inputs track it for relevant benchmark build/test caches. The README records the runtime and isolation invariants.

Exactly 48 CodSpeed identities change because their file paths move; all 132 workload names match. The six original benchmark paths remain. Runtime and worker changes also alter absolute performance baselines. Compare code changes with the same configuration on both sides; shifts against the previous setup are not router optimizations or regressions.

Validation

  • pnpm test:unit, pnpm test:types and pnpm test:eslint pass for affected projects and task dependencies. Nx reuses valid caches; the remaining SSR utility tests and affected type checks execute.
  • The SSR benchmark utility tests pass. During investigation, temporary configuration tests also verified actual CodSpeed/Vite flag merging, a Node hot-loop optimization trace, and a once-called function's baseline-compilation trace; those temporary tests are not retained in the PR.
  • Direct ESLint on modified TypeScript, Prettier, git diff --check and the offline workflow security check pass.
  • After simplifying the streaming scheduler to direct setImmediate calls, React, Solid and Vue builds pass. Each rebuilt handler passes the streaming response assertions for a sanity request and 16 concurrent requests. All six split React assets/serialization/rewrites cases passed locally; an AST comparison checked all 93 SSR workloads.
  • The selected five Linux CI repetitions each contain 132 fresh measurements, no optimized-out/significant-system-time warnings, matching workload sets and complete result pagination. Local macOS cannot execute CPU simulation.

Reproduce against an unchanged branch:

gh workflow run client-nav-benchmarks.yml --ref codex/stabilize-cpu-simulation

Wait for each run to finish before dispatching the next repetition at the same commit. Repeat five times, exclude memory results, verify complete fresh CPU-result coverage and calculate the per-benchmark spread defined above. The temporary CPU-only input and manual concurrency changes used during investigation are not retained in the PR; the workflow is unchanged from the implementation base.

Post-isolation experiment commits and CI runs

Four flags: remove only the heap overrideef00e4d015a82e6264e1d0bc3cf8d30ae574461c.

33973371004, 33973371983, 33973373355, 33973374620, 33973375866.

Stock CodSpeed runtime: no added flags0499502b9d54d2804d0474c0f4f7335f4ed18101.

33973481240, 33973482899, 33973484373.

Two upstream Node fixes only8d3c986f505f3d970cf39253c51632d1a06be501.

33973626220, 33973627252, 33973628425.

Upstream fixes + heap budgetaa87dc713e838c70b8ddfec6ceee83f49f6a0b63.

33975539435, 33975541195, 33975542465, 33975543777, 33975545229.

Upstream fixes + eager baseline + heap budget5dcdaa92015934633031479da015ef0edf67742b.

33977041102, 33977042635, 33977044106, 33977045809, 33977047895.

Upstream fixes + eager baseline; stock heap and marking tasksfbf0ea15e507639acd9a8b352d65057c20464afd.

33977180457, 33977181771, 33977183020 (cancelled), 33977184251 (cancelled), 33977185532 (cancelled).

Earlier experiments explaining the initial stabilization approach

These experiments preceded the flag-removal comparisons above and explain the initial five-flag proposal.

Early partial fixes were insufficient. Repeating them exposed outliers that were absent in their first two runs:

Full-suite configuration Repeats Worst spread Benchmarks >1% Benchmarks >3%
Original configuration 3 6.448% 12 1
Disable Maglev 3 7.330% 5 1
Also disable minor-GC tasks 5 6.252% 5 2
Also disable incremental-marking tasks 5 4.158% 5 2
Fixed initial heap and counted streaming turns 5 4.226% 1 1
Eager baseline; multiple workloads per worker 5 4.212% 2 2
Initial isolated-worker proposal: five flags 5 0.887% 0 0

The targeted comparison selected 18 Solid/Vue SSR measurements in streaming, global middleware and control flow. Both candidates below have the same counted-turn streaming change and three runtime flags. Only the initial heap flag differs:

Targeted configuration Complete repeats Worst of 18 Solid streaming spread
Without fixed initial heap 3 7.652% 4.184%
With fixed initial heap 3 0.257% 0.060%

Disabling incremental marking entirely was rejected: its two complete targeted runs had a worst spread above 9%. A third attempt was partial because the CodSpeed installer download lost its connection; it is excluded. The counted-turn change alone did not remove the streaming outlier, so it is not credited with that improvement.

Native profiles of the streaming outlier had identical application call counts, with additional cost concentrated in allocation-heavy functions. Local GC tracing of a standalone Solid SSR workload retained 13 allocation-triggered scavenges in the measured invocation with and without the fixed initial budget. The fixed budget removed incremental-marking activity during warmup in that reproduction. These traces support the runtime/heap explanation; the repeated Linux simulations establish the observed repeatability. They do not isolate every internal V8 operation responsible for each historical outlier.

Fresh-worker controls were the next decisive experiment: selecting only the React linked-CSS and plain-dehydration controls, with all five flags unchanged, produced three-run spreads of 0.018% and 0.086%. Both shared-worker cases had previously been outliers. The full integration then applied one workload per file to every SSR case, rather than special-casing those two.

Three clean Vue middleware builds produced byte-identical emitted artifacts. A task turn before GC allowed more warmup objects to be reclaimed, but three targeted runs still left a 4.10% linked-CSS spread. Adding GC and another cleanup turn still left 1.34%. Those hooks were removed. Disabling Sparkplug entirely left 1.41%; eager baseline compilation held the same assets workload to 0.65% across five repetitions. These are observed repeatability results; tracing with additional measurement markers did not directly catch baseline compilation inside the CSS measurement, so the exact contribution of compilation and heap layout is not fully isolated.

The pinned Node version is 24.8.0. The original control commit differs from the implementation base only in the manual workflow support, so it measures the original benchmark runtime/workloads. The final worker-isolation comparison retains the same five runtime flags and benchmark calls as the preceding candidate. These experiments narrow the sources of instability, but do not establish a unique internal V8 explanation for every historical spike.

Original configuration — commit 002eda8a10b69426aad7ce0de4fc7860c31b6d16.

GitHub: 33959196258, 33959198216, 33959200409.

Disable Maglev — commit c3782a40360982521942417e4c3058d1a8707cbd.

GitHub: 33959197229, 33959199431, 33959201353.

Also disable minor-GC tasks — commit 347ecfa724588983673b1d05652ad480908e37b3.

GitHub: 33960606235, 33960607571, 33960608833, 33960997294, 33960998027.

Also disable incremental-marking tasks — commit d44ba4c42a3708a69b8e7d0f90536e075e929179.

GitHub: 33961681221, 33961682787, 33961684239, 33961685473, 33961686639.

Fixed initial heap and counted streaming turns — commit 3e0be7a0c67913ef476bb432636a32808df03d3b.

GitHub: 33965107993, 33965109291, 33965110654, 33965111891, 33965113523.

Eager baseline; multiple workloads per worker — commit 085581bc115799d643fcf26e8d257735d6a110cf.

GitHub: 33967663478, 33967664880, 33967666372, 33967667824, 33967668939.

Initial isolated-worker proposal: five flags — commit 504b6b4e549b2511a722c3d34f8a63f98c9e41f1.

GitHub: 33970160374, 33970161802, 33970163178, 33970164414, 33970165694.

The isolated React linked-CSS/plain-dehydration control experiment used 1b286aae70af2f92dc603e7e6ffd29aac35fef94: 33968947657, 33968948792, 33968949736.

All 132 benchmark spreads

Values are rounded to three decimal places; a displayed 0.000% need not be exactly zero.

Benchmark Original setup: 3 repeats Initial PR: 5 repeats Selected configuration: 5 repeats
ssr head (vue) 0.138% 0.346% 0.593%
ssr head (solid) 0.043% 0.420% 0.525%
client-nested-params navigation loop (vue) 0.051% 0.197% 0.465%
ssr request loop (vue) 0.086% 0.887% 0.460%
client-route-tree-scale navigation loop (solid) 0.032% 0.200% 0.399%
client-loaders navigation loop (vue) 0.053% 0.157% 0.268%
ssr before-load chain (react) 0.073% 0.083% 0.241%
client-links navigation loop (vue) 0.113% 0.059% 0.225%
client-rewrites navigation loop (vue) 0.009% 0.097% 0.171%
client-async-pipeline navigation loop (vue) 0.083% 0.184% 0.163%
ssr assets linked-css control (vue) 0.111% 0.026% 0.147%
ssr server-fn during document ssr (react) 0.372% 0.013% 0.140%
ssr assets linked-css control (react) 0.184% 0.021% 0.140%
ssr control-flow unmatched 404 (vue) 0.071% 0.029% 0.134%
client-route-tree-scale navigation loop (vue) 1.000% 0.133% 0.128%
ssr global-mw document (vue) 0.030% 0.049% 0.126%
ssr rewrite localized (vue) 0.215% 0.188% 0.126%
ssr before-load chain (solid) 0.056% 0.124% 0.124%
client-side navigation loop (react) 0.011% 0.053% 0.117%
ssr before-load chain (vue) 0.047% 0.075% 0.113%
ssr dehydrate plain control (react) 0.220% 0.194% 0.111%
client-history navigation loop (solid) 0.376% 0.235% 0.110%
client-async-pipeline navigation loop (react) 0.099% 0.125% 0.109%
ssr rewrite passthrough (react) 0.210% 0.188% 0.108%
ssr selective (react) 0.237% 0.072% 0.104%
client-route-tree-scale navigation loop (react) 1.490% 0.088% 0.103%
client-links navigation loop (react) 0.039% 0.124% 0.093%
ssr request loop (react) 0.119% 0.047% 0.092%
ssr loaders (react) 0.110% 0.316% 0.092%
ssr rewrite passthrough (solid) 0.210% 0.130% 0.088%
client-nested-params navigation loop (react) 0.064% 0.072% 0.081%
ssr dehydrate rich types (vue) 0.078% 0.068% 0.078%
ssr head (react) 1.748% 0.297% 0.074%
ssr request loop (solid) 0.549% 0.061% 0.072%
ssr server-route (solid) 0.145% 0.004% 0.067%
ssr rewrite passthrough (vue) 0.162% 0.063% 0.067%
ssr control-flow error 500 (solid) 0.101% 0.031% 0.066%
ssr assets linked-css control (solid) 0.108% 0.141% 0.065%
ssr control-flow route headers (solid) 0.218% 0.022% 0.065%
ssr global-mw document (solid) 0.900% 0.072% 0.064%
client-head navigation loop (vue) 0.196% 0.194% 0.064%
client-preload interaction loop (react) 0.133% 0.034% 0.062%
client-head navigation loop (react) 0.074% 0.038% 0.062%
ssr streaming deferred (react) 0.053% 0.081% 0.060%
ssr global-mw document (react) 0.276% 0.209% 0.060%
ssr dehydrate plain control (solid) 0.142% 0.051% 0.057%
ssr rewrite localized (solid) 0.115% 0.031% 0.056%
ssr loaders (vue) 0.103% 0.075% 0.055%
ssr control-flow error 500 (vue) 0.095% 0.040% 0.054%
ssr dehydrate rich types (react) 0.433% 0.065% 0.052%
ssr server-fn during document ssr (vue) 1.728% 0.038% 0.051%
ssr not-found (solid) 0.033% 0.061% 0.048%
ssr assets inline-css cdn (solid) 0.096% 0.041% 0.045%
ssr server-route (react) 0.020% 0.016% 0.042%
ssr streaming deferred (vue) 0.188% 0.019% 0.042%
ssr control-flow route headers (vue) 0.105% 0.039% 0.042%
client-preload interaction loop (vue) 0.274% 0.360% 0.041%
ssr not-found (vue) 0.032% 0.025% 0.041%
ssr dehydrate rich types (solid) 6.448% 0.066% 0.040%
ssr assets inline-css cdn (vue) 0.101% 0.084% 0.039%
ssr server-fn raw-response (vue) 0.350% 0.061% 0.039%
ssr selective (vue) 0.118% 0.021% 0.039%
ssr loaders (solid) 0.125% 0.056% 0.036%
client-search-params navigation loop (react) 0.258% 0.034% 0.036%
ssr dehydrate plain control (vue) 0.997% 0.108% 0.036%
ssr rewrite localized (react) 0.092% 0.033% 0.035%
ssr server-fn multipart (solid) 2.680% 0.019% 0.035%
ssr control-flow route headers (react) 1.679% 0.026% 0.035%
ssr server-fn raw-response (solid) 1.471% 0.015% 0.034%
client-head navigation loop (solid) 1.800% 0.187% 0.034%
client-control-flow navigation loop (react) 0.018% 0.077% 0.034%
ssr server-fn redirect (vue) 0.040% 0.026% 0.033%
client-history navigation loop (react) 0.380% 0.022% 0.032%
ssr server-route (vue) 0.000% 0.030% 0.031%
ssr assets inline-css cdn (react) 0.042% 0.019% 0.031%
ssr global-mw server-route (react) 0.399% 0.015% 0.030%
ssr server-fn send-context (solid) 0.109% 0.003% 0.030%
ssr control-flow error 500 (react) 1.041% 0.062% 0.029%
client-rewrites navigation loop (react) 0.126% 0.003% 0.029%
client-rewrites navigation loop (solid) 0.022% 0.217% 0.029%
ssr server-fn multipart (react) 0.093% 0.017% 0.028%
client-history navigation loop (vue) 0.039% 0.006% 0.027%
ssr global-mw server-route (solid) 0.163% 0.015% 0.026%
client-preload interaction loop (solid) 0.266% 0.113% 0.026%
ssr server-fn multipart (vue) 0.060% 0.011% 0.026%
ssr control-flow unmatched 404 (solid) 0.153% 0.039% 0.024%
ssr selective (solid) 0.066% 0.040% 0.024%
ssr streaming deferred (solid) 0.097% 0.032% 0.024%
ssr not-found (react) 0.026% 0.066% 0.023%
client-control-flow navigation loop (vue) 0.099% 0.054% 0.023%
ssr server-fn POST (vue) 0.135% 0.001% 0.022%
ssr server-fn redirect (react) 0.171% 0.025% 0.022%
ssr server-fn during document ssr (solid) 0.363% 0.096% 0.021%
client-async-pipeline navigation loop (solid) 0.084% 0.025% 0.020%
ssr server-fn send-context (vue) 0.072% 0.014% 0.018%
client-search-params navigation loop (vue) 0.291% 0.104% 0.017%
ssr global-mw server-fn (react) 0.230% 0.132% 0.017%
client-mount loop (react) 0.153% 0.015% 0.016%
ssr server-fn raw-stream (vue) 0.016% 0.004% 0.016%
ssr control-flow unmatched 404 (react) 0.696% 0.037% 0.015%
ssr server-route middleware (react) 0.027% 0.154% 0.014%
ssr server-fn raw-stream (react) 0.097% 0.026% 0.013%
ssr server-fn not-found (vue) 0.077% 0.004% 0.012%
client-side navigation loop (solid) 0.246% 0.235% 0.012%
client-mount loop (solid) 0.476% 0.034% 0.012%
ssr global-mw server-route (vue) 0.055% 0.034% 0.012%
ssr server-fn raw-response (react) 0.057% 0.027% 0.012%
ssr server-route middleware (solid) 0.106% 0.003% 0.012%
ssr server-fn raw-stream (solid) 1.912% 0.007% 0.012%
ssr global-mw server-fn (solid) 1.622% 0.020% 0.011%
ssr server-fn GET (vue) 0.143% 0.052% 0.009%
ssr server-fn redirect (solid) 0.110% 0.032% 0.008%
ssr server-fn POST (solid) 0.031% 0.053% 0.007%
ssr redirect (solid) 0.021% 0.017% 0.007%
ssr redirect (react) 0.044% 0.023% 0.007%
client-loaders navigation loop (solid) 0.148% 0.010% 0.007%
ssr server-fn POST (react) 0.110% 0.070% 0.006%
ssr server-fn send-context (react) 0.057% 0.009% 0.006%
ssr server-route middleware (vue) 0.009% 0.015% 0.006%
client-control-flow navigation loop (solid) 0.072% 0.145% 0.005%
ssr server-fn GET (solid) 0.044% 0.021% 0.005%
client-links navigation loop (solid) 0.576% 0.267% 0.005%
client-nested-params navigation loop (solid) 0.509% 0.109% 0.004%
ssr server-fn not-found (react) 0.164% 0.016% 0.004%
client-mount loop (vue) 0.274% 0.161% 0.003%
ssr redirect (vue) 0.070% 0.033% 0.001%
client-loaders navigation loop (react) 0.140% 0.042% 0.001%
ssr server-fn GET (react) 0.002% 0.062% 0.001%
ssr global-mw server-fn (vue) 0.341% 0.085% 0.000%
client-side navigation loop (vue) 0.234% 0.022% 0.000%
client-search-params navigation loop (solid) 0.434% 0.057% 0.000%
ssr server-fn not-found (solid) 0.149% 0.024% 0.000%

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with the relevant test commands, or tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Benchmarking

    • Added SSR benchmark coverage for control-flow, rewrites, serialization, server functions, middleware, transport, and asset scenarios across React, Solid, and Vue.
    • Added client-navigation and SSR benchmark execution consistency through standardized CPU-simulation settings and isolated test runs.
    • Separated benchmark scenarios into individually runnable cases for clearer performance results.
  • Documentation

    • Expanded benchmark setup, workload isolation, timing behavior, repeatability guidance, and runtime configuration details.
  • Maintenance

    • Updated benchmark type-checking and cache inputs to include the expanded benchmark configurations.

@Sheraff
Sheraff requested a review from a team as a code owner September 5, 2026 14:32
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T14:36:14.084683Z 504b6b4 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@nx-cloud

nx-cloud Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 6741406

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 11m 59s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 2m 15s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-05 18:20:25 UTC

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 65a57a5f-9e2a-4597-8646-d8bb2ede8fbb

📥 Commits

Reviewing files that changed from the base of the PR and between 12a83c0 and 6741406.

📒 Files selected for processing (4)
  • benchmarks/README.md
  • benchmarks/ssr/package.json
  • benchmarks/ssr/scenarios/streaming/shared-data.ts
  • benchmarks/ssr/tsconfig.json
💤 Files with no reviewable changes (1)
  • benchmarks/ssr/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • benchmarks/README.md

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The benchmark suite now applies shared CPU-simulation flags, isolates SSR benchmark workers, splits SSR scenarios into separate files, widens benchmark TypeScript includes, updates streaming scheduling, and revises benchmark runtime documentation.

Changes

Benchmark runtime and workload coverage

Layer / File(s) Summary
Client navigation runtime configuration
benchmarks/client-nav/**/vite.config.ts
Client navigation benchmarks now pass cpuSimulationExecArgv() to Vitest through test.execArgv.
SSR workload separation and runtime wiring
benchmarks/ssr/**
SSR scenarios move into separate speed*.bench.ts files. SSR Vite configs apply CPU-simulation arguments and enable isolation.
Runtime helper, type inputs, and benchmark documentation
benchmarks/cpu-simulation.ts, benchmarks/tsconfig.json, benchmarks/ssr/tsconfig.json, benchmarks/ssr/package.json, nx.json, benchmarks/ssr/scenarios/streaming/shared-data.ts, benchmarks/README.md
The shared helper returns simulation flags without --no-incremental-marking-task. Type-check inputs, streaming task scheduling, and benchmark documentation are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 67414

This change updates benchmark execution isolation, CPU-simulation settings, fixture scheduling, and benchmark cache configuration without changing production router behavior. The supplied validation and benchmark results indicate no remaining merge-blocking risk.

Suggested reviewers: schiller-manuel

Sequence Diagram(s)

sequenceDiagram
  participant Vitest
  participant cpuSimulationExecArgv
  participant SSRBenchmark
  participant BuiltServerHandler
  Vitest->>cpuSimulationExecArgv: Resolve execution arguments
  cpuSimulationExecArgv-->>Vitest: Return runtime flags
  Vitest->>SSRBenchmark: Start isolated speed file
  SSRBenchmark->>BuiltServerHandler: Load and validate handler
  SSRBenchmark->>BuiltServerHandler: Run scenario request loop
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 51 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: CPU simulation stabilization through isolated SSR workers and explicit V8 settings.
Description check ✅ Passed The description includes the required Changes, Checklist, and Release Impact sections. It explains the motivation, implementation, validation results, and confirms the change is development, CI, and d…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 51 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/stabilize-cpu-simulation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

5 package(s) bumped directly, 18 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/react-router 1.170.32 → 1.170.33 Changeset
@tanstack/router-core 1.171.27 → 1.171.28 Changeset
@tanstack/solid-router 1.170.30 → 1.170.31 Changeset
@tanstack/start-plugin-core 1.171.39 → 1.171.40 Changeset
@tanstack/vue-router 1.170.29 → 1.170.30 Changeset
@tanstack/react-start 1.168.49 → 1.168.50 Dependent
@tanstack/react-start-client 1.168.30 → 1.168.31 Dependent
@tanstack/react-start-rsc 0.1.48 → 0.1.49 Dependent
@tanstack/react-start-server 1.167.37 → 1.167.38 Dependent
@tanstack/router-cli 1.167.33 → 1.167.34 Dependent
@tanstack/router-generator 1.167.33 → 1.167.34 Dependent
@tanstack/router-plugin 1.168.35 → 1.168.36 Dependent
@tanstack/router-vite-plugin 1.167.35 → 1.167.36 Dependent
@tanstack/solid-start 1.168.47 → 1.168.48 Dependent
@tanstack/solid-start-client 1.168.29 → 1.168.30 Dependent
@tanstack/solid-start-server 1.167.36 → 1.167.37 Dependent
@tanstack/start-client-core 1.170.27 → 1.170.28 Dependent
@tanstack/start-server-core 1.169.31 → 1.169.32 Dependent
@tanstack/start-static-server-functions 1.167.32 → 1.167.33 Dependent
@tanstack/start-storage-context 1.167.29 → 1.167.30 Dependent
@tanstack/vue-start 1.168.46 → 1.168.47 Dependent
@tanstack/vue-start-client 1.167.32 → 1.167.33 Dependent
@tanstack/vue-start-server 1.167.36 → 1.167.37 Dependent

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

This pull request does not affect bundle size in any measured scenario.

@pkg-pr-new

pkg-pr-new Bot commented Sep 5, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@8248

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@8248

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@8248

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@8248

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@8248

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@8248

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@8248

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@8248

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@8248

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@8248

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@8248

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@8248

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@8248

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@8248

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@8248

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@8248

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@8248

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@8248

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@8248

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@8248

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@8248

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@8248

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@8248

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@8248

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@8248

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@8248

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@8248

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@8248

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@8248

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@8248

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@8248

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@8248

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@8248

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@8248

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@8248

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@8248

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@8248

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@8248

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@8248

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@8248

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@8248

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@8248

commit: 6741406

@codspeed-hq

codspeed-hq Bot commented Sep 5, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 26.53%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 6 improved benchmarks
❌ 88 (👁 88) regressed benchmarks
✅ 38 untouched benchmarks
🆕 48 new benchmarks
⏩ 48 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation ssr global-mw document (solid) 352.4 ms 282.6 ms +24.69%
Simulation ssr global-mw document (react) 298.3 ms 269.3 ms +10.76%
Memory mem client mount-unmount (solid) 513.7 KB 483.3 KB +6.3%
Memory mem server error-paths redirect (react) 317.8 KB 302.1 KB +5.19%
Simulation client-mount loop (react) 73.8 ms 70.4 ms +4.88%
Memory mem server error-paths not-found (solid) 577.2 KB 554.5 KB +4.08%
🆕 Simulation ssr assets linked-css control (solid) N/A 208.2 ms N/A
🆕 Simulation ssr control-flow error 500 (solid) N/A 211 ms N/A
🆕 Simulation ssr control-flow route headers (solid) N/A 288.6 ms N/A
🆕 Simulation ssr control-flow unmatched 404 (solid) N/A 212.8 ms N/A
🆕 Simulation ssr not-found (solid) N/A 179.9 ms N/A
🆕 Simulation ssr global-mw server-fn (solid) N/A 232.1 ms N/A
🆕 Simulation ssr global-mw server-route (solid) N/A 205.6 ms N/A
🆕 Simulation ssr rewrite passthrough (solid) N/A 263.4 ms N/A
🆕 Simulation ssr dehydrate plain control (solid) N/A 223.7 ms N/A
🆕 Simulation ssr server-fn raw-response (solid) N/A 196.7 ms N/A
🆕 Simulation ssr server-fn raw-stream (solid) N/A 731.1 ms N/A
🆕 Simulation ssr server-fn during document ssr (solid) N/A 218.6 ms N/A
🆕 Simulation ssr server-fn not-found (solid) N/A 254.1 ms N/A
🆕 Simulation ssr server-fn POST (solid) N/A 270.4 ms N/A
... ... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing codex/stabilize-cpu-simulation (6741406) with main (28a5e45)

Open in CodSpeed

Footnotes

  1. 48 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.

@Sheraff
Sheraff merged commit 09da932 into main Sep 5, 2026
26 checks passed
@Sheraff
Sheraff deleted the codex/stabilize-cpu-simulation branch September 5, 2026 18:54
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.

2 participants