next build workers strip --max-old-space-size (isolatedMemory) and expose no memory control — page-data collection OOMs, bundler-independent
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/alexboii/next-build-worker-oom
To Reproduce
git clone https://github.com/alexboii/next-build-worker-oom && cd next-build-worker-oom
docker run --rm -m 4g --cpus 4 -v "$PWD":/app -w /app node:22 bash -c \
'npm install --no-audit --no-fund && npx next build'
The repo contains 12 generated modules that allocate ~150MB each at import time (a stand-in for a large real-world module graph) and 30 Pages Router pages with getStaticProps importing them. Full 5-run matrix in the README.
Current vs. Expected behavior
Current (verified in the container above, output committed to the README):
| # | Command | Result |
|---|---|---|
| 1 | npx next build (11 workers) |
⨯ Next.js build worker exited with code: null and signal: SIGKILL at Collecting page data |
| 2 | NODE_OPTIONS=--max-old-space-size=1024 npx next build |
identical SIGKILL — the heap cap has no effect on workers |
| 3 | experimental.cpus: 1 |
passes |
| 4 | experimental.cpus: 1 + NODE_OPTIONS=--max-old-space-size=1024 |
passes — the single worker resident-allocates ~1.8GB yet "respects" a 1GB cap, which is only possible because the flag never reaches the worker |
| 5 | npx next build --webpack (11 workers) |
same SIGKILL — bundler-independent |
Cause: createStaticWorker passes isolatedMemory: true (packages/next/src/build/index.ts, comment: "remove --max-old-space-size flag as it can cause memory issues"), and the Worker wrapper deletes the flag (packages/next/src/lib/worker.ts: delete nodeOptions['max-old-space-size']). jest-worker's workerIdleMemoryLimit is not plumbed through either — so no configuration bounds build-worker memory at all.
Run 3's "just lower cpus" is not viable at real scale: experimental.cpus also sizes static-generation workers, whose memory scales the opposite way (fewer workers ⇒ more pages each ⇒ more memory each). On our production monorepo (~83 static pages, several hundred routes), static generation needs ≥14 workers while page-data collection OOMs at 14 on a 30-vCPU/60GB machine (Vercel's largest) — the window is empty, and we were forced fleet-wide back to webpack + cpus: 2, which fits in 16GB. One knob, two opposing constraints, zero memory control.
Expected — any one of:
- An opt-in per-worker heap cap (don't strip
--max-old-space-sizewhen the user explicitly opts in, e.g.experimental.staticWorkerMaxOldSpaceSize), or - Memory-bounded worker recycling (expose
workerIdleMemoryLimit), or - Separate worker-count knobs for page-data collection vs static generation (or share/cache the collected page-data module graph across workers).
Previously filed as #95744 (closed for missing repro link — this issue adds the public reproduction).
Provide environment information
Operating System:
Platform: linux
Arch: arm64
Version: #1 SMP Mon Feb 24 16:35:16 UTC 2025
Available memory (MB): 7838 (container capped at 4096)
Available CPU cores: 12 (container capped at 4)
Binaries:
Node: 22.23.1
npm: 10.9.8
Relevant Packages:
next: 16.3.0-preview.5 // Latest available version is detected (16.3.0-preview.5).
react: 19.2.0
react-dom: 19.2.0
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Performance, Turbopack, Webpack
Which stage(s) are affected? (Select all that apply)
next build (local), Vercel (Deployed)
Additional context
Also reproduced on Vercel build machines: a production app that builds with webpack in a 16GB container OOMs under Turbopack on the 30-vCPU/60GB Turbo machine, dying 27 seconds into Collecting page data using 14 workers. Happy to provide NEXT_TURBOPACK_TRACING traces privately.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the Docker reproduction from alexboii/next-build-worker-oom and compare the documented five-run matrix. Read packages/next/src/build/index.ts around createStaticWorker and packages/next/src/lib/worker.ts where max-old-space-size is removed, then trace how worker memory settings are configured. Done means an agreed memory-control approach is implemented and the reproduction no longer OOMs during page-data collection.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nextjs, node.js
- Domain
- build-system, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 39/100