Skip to content

[code-infra] Run the browser tests with one page per project - #23461

Open
LukasTy wants to merge 2 commits into
mui:masterfrom
LukasTy:code-infra/browser-tests-single-worker
Open

[code-infra] Run the browser tests with one page per project#23461
LukasTy wants to merge 2 commits into
mui:masterfrom
LukasTy:code-infra/browser-tests-single-worker

Conversation

@LukasTy

@LukasTy LukasTy commented Aug 31, 2026

Copy link
Copy Markdown
Member

Vitest opens maxWorkers pages per project and keeps every one of them alive until the whole run ends (vitest#10990). The peak renderer count is therefore projects * maxWorkers, not anything bounded by the work left to do. With 21 browser projects and maxWorkers: 2 that is 42 Chromium renderers alive at once, which is what puts test_browser near the memory ceiling of its container and produces the intermittent Browser page crashed / Browser connection was closed failures.

Setting VITEST_MAX_WORKERS=1 halves that.

Measured

Full suite, cold dependency cache, same machine. Memory is phys_footprint summed across the renderer processes - RSS is not trustworthy here because it counts shared pages once per process, and it reported only a 10% drop for the same change.

before after
peak renderer processes 43 21
total renderer footprint 11535 MB 6702 MB (-42%)
footprint per renderer 275 MB 335 MB
wall time 175s ~190s (+10%)
result 739 passed, 8 skipped 739 passed, 8 skipped

Footprint per renderer goes up, because each remaining page now runs about twice as many files and isolate is off, so it accumulates more. Halving the process count more than compensates.

On a 16 GB container this is roughly 11.5 GB -> 6.7 GB of renderers, which turns "running at the ceiling" into about 5 GB of headroom.

CircieCI results

https://app.circleci.com/pipelines/github/mui/mui-x/139278/workflows/a5ed8196-8eb3-431f-9b0d-13b66be8fece/jobs/903571/resources CI is sitting happily at ~75% RAM usage.

Looks like a decent compromise for the time being.

Why the env var and not a flag

--maxWorkers=1 on the command line does not reach the projects: the per-project value from vitest.shared.mts wins, so the flag looks like a no-op. Vitest applies VITEST_MAX_WORKERS last, inside each project's own config resolution, so it is the one that propagates.

Same four projects (x-charts*), same run, for illustration:

setting renderers
VITEST_MAX_WORKERS=1 4
current config (maxWorkers: 2) 8
CLI --maxWorkers=1 8
VITEST_MAX_WORKERS=7 23

Worth noting the last row: higher values are much worse, roughly 6 renderers per project.

Scope

One env var on the test_browser job, so it covers test_browser and test_browser_react_18 and nothing else. maxWorkers: 2 stays in vitest.shared.mts for local runs and for the jsdom job, which shards with --no-file-parallelism and does not have this problem.

This does not fix the underlying issue - pages of finished projects still stay open until the end of the run, which is what vitest#10991 addresses. It buys enough headroom in the meantime, without sharding, report merging, or waiting on an upstream release.

Confirmed on CI

The table above was measured on a macOS laptop, so the container was the real test. It agrees: the test_browser job now peaks under 75% of the container's RAM, where it previously ran at the ceiling. All 12 CircleCI jobs pass.

One note for anyone reading the check history: test_browser_react_18 failed once on an earlier run, on dependencyArrows.EventTimelinePremium.test.tsx. That is the roaming act-warning flake on that job, not this change - three unrelated branches hit it on three different files within 40 minutes that morning, one of them going green on retry, and it passed here on a re-run of identical code. x-scheduler-premium also passes locally at both VITEST_MAX_WORKERS=1 and =2.

Vitest opens `maxWorkers` pages per project and keeps every one of them until
the whole run ends (vitest-dev/vitest#10990), so the
peak renderer count is `projects * maxWorkers` rather than anything bounded by
the work left to do. With 21 browser projects and `maxWorkers: 2` that is 42
Chromium renderers alive at once, which is what puts the job near the memory
ceiling of its container.

Setting `VITEST_MAX_WORKERS=1` halves it. Measured locally on the full suite
with a cold dependency cache:

  peak renderers                43     -> 21
  total renderer footprint   11535MB   -> 6702MB   (-42%)
  wall time                    175s    -> ~190s    (+10%)

The env var is required: a `--maxWorkers` CLI flag does not reach the projects,
because the per-project value from `vitest.shared.mts` wins. Vitest applies the
env var last, inside each project's own config resolution.

Co-Authored-By: Claude Opus 5 <[email protected]>
@code-infra-dashboard

code-infra-dashboard Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-23461--material-ui-x.netlify.app/
QR code for https://deploy-preview-23461--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-scheduler 0B(0.00%) 0B(0.00%)
@mui/x-scheduler-premium 0B(0.00%) 0B(0.00%)
@mui/x-chat 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

Total duration: 1,612.87 ms +73.47 ms(+4.8%) | Renders: 63 (+0) | Paint: 2,210.70 ms +120.69 ms(+5.8%)

Test Duration Renders
LineChart stacked area with multiple series 441.30 ms 🔺+147.75 ms(+50.3%) 2 (+0)
LineChart with big data amount (with marks) 66.24 ms 🔺+22.07 ms(+50.0%) 2 (+0)
LineChart with date axis and big data amount 46.34 ms 🔺+17.34 ms(+59.8%) 2 (+0)
Area chart with big data amount (no marks) 63.73 ms 🔺+13.07 ms(+25.8%) 2 (+0)
RadarChart with many axes and multiple series 10.51 ms 🔺+2.76 ms(+35.6%) 2 (+0)

…and 10 more (+11 within noise) — details

Metric alarms

Test Metric Change
LineChart stacked area with multiple series bench:paint 🔺 +154.69 ms
LineChart with big data amount (with marks) bench:paint 🔺 +21.38 ms
LineChart with date axis and big data amount bench:paint 🔺 +30.68 ms
Area chart with big data amount (no marks) bench:paint 🔺 +31.17 ms
RadarChart with many axes and multiple series bench:paint 🔺 +5.45 ms

…and 2 more metric alarms — details


Check out the code infra dashboard for more information about this PR.

@LukasTy
LukasTy marked this pull request as draft August 31, 2026 09:19
@LukasTy LukasTy self-assigned this Aug 31, 2026
@LukasTy LukasTy added test type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). labels Aug 31, 2026
Master has not moved since the branch was cut, so there is nothing to merge.
The `test_browser_react_18` failure was the roaming act-warning flake: three
unrelated branches hit it within 40 minutes on three different test files, and
one went green on retry.
@LukasTy
LukasTy marked this pull request as ready for review August 31, 2026 10:18
@JCQuintas

JCQuintas commented Aug 31, 2026

Copy link
Copy Markdown
Member

On CI the wall time cost is bigger than local.

155.9s here (186s job) vs 112-134s (141-167s job) on five master runs from today.

About 25-35% change

Retrying is slower though 🤷

@LukasTy

LukasTy commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

Yeah, this is slightly more expensive per run, but if it buys us stable CI until Vitest resolves their internals, I think it would end up being net positive.
Waiting for input from @Janpot before proceeding.

@Janpot Janpot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Have nothing against it. So far it seems stable at the moment. We could also keep this in the back pocket for when it starts flaking again. Whichever goes first, @JCQuintas PR at vitest, or MUI X adds another big feature.

@LukasTy

LukasTy commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

Fair enough. We pulled a few levers now. We can keep the current approach until we see OOM issues again. 👌
Although we are "flying very close to the sun". Memory climbs to 99% on most runs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). test type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants