Reproduction link or steps
Workload-dependent bloat on a large monorepo. I do not have a minimal stackblitz repro yet — happy to bisect/profile further if the maintainers point at suspect areas.
Public repo used for the comparison: https://github.com/lobehub/lobehub
Branch / pinned package state: canary (currently vite ^8.0.9, @vitejs/plugin-react ^5.1.4).
Steps (both runs in the same checkout, only swapping vite + plugin-react versions; backend Next.js was NOT started, only the SPA dev server):
pnpm install
pnpm run dev:spa (which runs vite --port 9876 against the repo's vite.config.ts)
- Wait until
VITE … ready
- Headless Chrome via Playwright
page.goto(/) + waitForTimeout(25_000) — this is important; vite triggers ✨ new dependencies optimized → reloading ~20–28 s after ready, so a shorter window catches the page mid-reload, not its settled first paint. Both versions render the same SPA home (sidebar Search / Home / Tasks / Pages / Agents / Generation / Community / Resources + chat input + model picker), with pageErrors empty and the only console errors being the expected 500/502 on TRPC because no backend is running.
- Sample the entire process tree with
vmmap -summary <pid> plus children.
For the v7 control I had to:
- Pin
vite ^7.3.3, @vitejs/plugin-react ^4.7.0.
- Drop
experimental.bundledDev: false (v8-only).
- Drop
build.rolldownOptions (v8-only).
- Replace
resolve: { tsconfigPaths: true } (v8-only) with the vite-tsconfig-paths plugin.
The same v7-compatible vite.config.ts was used for the v8 run as well, so the only variables across the two runs are the vite + plugin-react versions themselves.
What is expected?
Vite 8 dev memory should be in the same order of magnitude as vite 7 for the same workload — ideally lower, since rolldown is intended to be a more efficient bundler than esbuild + rollup. At minimum the integrated single-process design should not regress total physical footprint vs v7's two-process model.
What is actually happening?
vite 8's main node process plateaus at ~7-9 GB physical memory while vite 7's process tree (main + esbuild service) settles under 1 GB on the same workload — roughly +7× on tree physical footprint, +4–5× on peak.
|
vite 7.3.3 |
vite 8.0.11 (rolldown 1.0.0-rc.18) |
| ready (cold) |
487 ms |
481 ms |
| processes |
2 (node + esbuild service) |
1 (node only) |
| RSS · main node |
723 MB |
8 410 MB |
| RSS · esbuild service child |
2 996 MB (mmap-inflated) |
— |
| RSS · tree |
3 719 MB |
8 410 MB |
vmmap Physical footprint · main |
706 MB (peak 2.0 GB) |
6.7 GB (peak 9.3 GB) |
| Physical footprint · esbuild child |
174 MB (peak 5.6 GB) |
— |
| Physical footprint · tree |
~880 MB |
~6.7 GB |
Notes on methodology:
- macOS
RSS for the esbuild Go process is mmap-inflated; vmmap "Physical footprint" is the more reliable cross-process metric.
experimental.bundledDev is at its default false, so rolldown's dev engine itself is not driving the workload — the increase appears in the regular dep-optimize / module-graph dev path that now routes through rolldown instead of esbuild.
- I posted earlier numbers in this issue claiming +50%; those were wrong because (a) the chrome warmup window I used was shorter than the time it takes for the
optimized dependencies changed → reloading cycle to settle, and (b) I was sampling v7's esbuild during its transient post-bundle peak, before the service idled back down to ~174 MB. The numbers above are the corrected, fully-settled measurement. See the comment on this issue for the full methodology trace.
System Info
System:
OS: macOS 26.4.1
CPU: (10) arm64 Apple M5
Memory: 9.12 GB free / 32.00 GB
Binaries:
Node: 24.15.0
pnpm: 10.33.0
npm: 11.6.2
Browsers:
Chrome: 147.0.7727.138
npmPackages (vite 8 run):
vite: 8.0.11
@vitejs/plugin-react: 5.2.0
rolldown (bundled): 1.0.0-rc.18
npmPackages (vite 7 control):
vite: 7.3.3
@vitejs/plugin-react: 4.7.0
vite-tsconfig-paths: 6.1.1
Any additional comments?
- This is workload-dependent: the lobe-chat monorepo has a heavy
server.warmup.clientFiles glob pre-bundling many packages/**/src/**/*.ts files. I assume that interacts with rolldown's dep handling more aggressively than v7's esbuild.
- I have not bisected
@vitejs/plugin-react 4 → 5 separately, so a non-zero share of the regression could live there rather than in rolldown — but plugin-react@5 is required by vite 8, so users cannot avoid it on v8.
- Filing here per the discussion that vite 8 dev now goes through rolldown end-to-end. Happy to refile at
vitejs/vite if this is more appropriately routed there.
- I also bisected across all 31 publicly released vite 8 versions (19 betas + 12 stables); see the bisect comment for the table. Short version: the regression is present from
8.0.0-beta.0 (rolldown 1.0.0-beta.53) onward — there is no within-8.x patch where the footprint jumps. The slow drift across stables (8.0.0 ~6.2 GB → 8.0.11 ~6.9 GB) is dwarfed by the v7→v8 step.
- Happy to capture node
--inspect heap snapshots, run with RUSTFLAGS=-C debug-assertions=on, or share a profile of the napi binding allocations if any of that helps localize where the ~6 GB of resident memory in the rolldown native module lives.
Reproduction link or steps
Workload-dependent bloat on a large monorepo. I do not have a minimal stackblitz repro yet — happy to bisect/profile further if the maintainers point at suspect areas.
Public repo used for the comparison: https://github.com/lobehub/lobehub
Branch / pinned package state:
canary(currentlyvite ^8.0.9,@vitejs/plugin-react ^5.1.4).Steps (both runs in the same checkout, only swapping vite + plugin-react versions; backend Next.js was NOT started, only the SPA dev server):
pnpm installpnpm run dev:spa(which runsvite --port 9876against the repo'svite.config.ts)VITE … readypage.goto(/) + waitForTimeout(25_000)— this is important; vite triggers✨ new dependencies optimized → reloading~20–28 s afterready, so a shorter window catches the page mid-reload, not its settled first paint. Both versions render the same SPA home (sidebarSearch / Home / Tasks / Pages / Agents / Generation / Community / Resources+ chat input + model picker), withpageErrorsempty and the only console errors being the expected 500/502 on TRPC because no backend is running.vmmap -summary <pid>plus children.For the v7 control I had to:
vite ^7.3.3,@vitejs/plugin-react ^4.7.0.experimental.bundledDev: false(v8-only).build.rolldownOptions(v8-only).resolve: { tsconfigPaths: true }(v8-only) with thevite-tsconfig-pathsplugin.The same v7-compatible
vite.config.tswas used for the v8 run as well, so the only variables across the two runs are the vite + plugin-react versions themselves.What is expected?
Vite 8 dev memory should be in the same order of magnitude as vite 7 for the same workload — ideally lower, since rolldown is intended to be a more efficient bundler than esbuild + rollup. At minimum the integrated single-process design should not regress total physical footprint vs v7's two-process model.
What is actually happening?
vite 8's main node process plateaus at ~7-9 GB physical memory while vite 7's process tree (main + esbuild service) settles under 1 GB on the same workload — roughly +7× on tree physical footprint, +4–5× on peak.
vmmapPhysical footprint · mainNotes on methodology:
RSSfor the esbuild Go process is mmap-inflated;vmmap"Physical footprint" is the more reliable cross-process metric.experimental.bundledDevis at its defaultfalse, so rolldown's dev engine itself is not driving the workload — the increase appears in the regular dep-optimize / module-graph dev path that now routes through rolldown instead of esbuild.optimized dependencies changed → reloadingcycle to settle, and (b) I was sampling v7's esbuild during its transient post-bundle peak, before the service idled back down to ~174 MB. The numbers above are the corrected, fully-settled measurement. See the comment on this issue for the full methodology trace.System Info
Any additional comments?
server.warmup.clientFilesglob pre-bundling manypackages/**/src/**/*.tsfiles. I assume that interacts with rolldown's dep handling more aggressively than v7's esbuild.@vitejs/plugin-react4 → 5 separately, so a non-zero share of the regression could live there rather than in rolldown — but plugin-react@5 is required by vite 8, so users cannot avoid it on v8.vitejs/viteif this is more appropriately routed there.8.0.0-beta.0(rolldown1.0.0-beta.53) onward — there is no within-8.x patch where the footprint jumps. The slow drift across stables (8.0.0 ~6.2 GB → 8.0.11 ~6.9 GB) is dwarfed by the v7→v8 step.--inspectheap snapshots, run withRUSTFLAGS=-C debug-assertions=on, or share a profile of the napi binding allocations if any of that helps localize where the ~6 GB of resident memory in the rolldown native module lives.