/commands/nodejs/increase-memory-limit-max-old-space-size
node --max-old-space-size=4096: increase the Node.js heap memory limit
- tool
- Node.js
- versions
- Node.js 12+
- os
- any
node --max-old-space-size=4096 app.js raises the size limit of V8's old-generation heap to 4096 MiB for that process. Use it when a build, test run or script crashes with FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory. For tools you start through npm, npx or a CLI wrapper, set it in NODE_OPTIONS instead, so every Node.js process they spawn gets it.
Set it and check the new limit
node --max-old-space-size=2048 -e 'console.log(Math.round(require("v8").getHeapStatistics().heap_size_limit / 1048576))'
NODE_OPTIONS="--max-old-space-size=8192" node -e 'console.log(Math.round(require("v8").getHeapStatistics().heap_size_limit / 1048576))'Output
2240 8384
v8.getHeapStatistics().heap_size_limit is the limit V8 applies, in bytes. It comes out a little higher than the value you pass because it also counts the young generation, which --max-old-space-size does not include. Without the flag the default depends on the Node.js version and on the memory the system (or the container) reports, so print it on the machine that crashes rather than assuming a number.
Where to put it
| Situation | How to set it |
|---|---|
| A script you run yourself | node --max-old-space-size=4096 script.js |
| npm scripts, npx, webpack, Vite, Jest, tsc | NODE_OPTIONS="--max-old-space-size=4096" npm run build |
| Windows cmd.exe | set NODE_OPTIONS=--max-old-space-size=4096 then run the command |
| Windows PowerShell | $env:NODE_OPTIONS="--max-old-space-size=4096" then run the command |
| Docker image | ENV NODE_OPTIONS=--max-old-space-size=1536 in the Dockerfile |
| GitHub Actions | env: NODE_OPTIONS: --max-old-space-size=4096 on the step or job |
| A child process only | Pass execArgv or NODE_OPTIONS in the env of child_process.fork |
The value is in mebibytes (MiB) and has no unit suffix: 4096, not 4GB. NODE_OPTIONS accepts only flags that Node.js allows there, and --max-old-space-size is one of them. Command-line flags given to node directly are applied after NODE_OPTIONS, so they win when both set the same option.
Pitfalls
- Containers. Raising the heap above the container memory limit replaces a clear V8 error with the process being killed by the kernel out-of-memory killer (exit code 137).
- 32-bit and small machines. You cannot get more heap than the address space and the RAM allow; on a 1 GiB machine a 4096 limit only changes how the crash looks.
- Wrappers that spawn workers. Some tools run work in child processes or worker threads.
NODE_OPTIONSreaches child processes; a flag on the parent's command line does not. - Typos are silent in some wrappers. A misspelt flag passed directly to
nodestops it withbad option, but a tool that swallows unknown options leaves the default in place. Printheap_size_limitas above to be sure.
Related flags
--max-semi-space-size sizes the young generation (useful for allocation-heavy workloads), --heapsnapshot-near-heap-limit=N writes up to N heap snapshots when the heap is close to the limit, and --trace-gc logs every garbage collection. A crash for lack of memory ends the process with a non-zero exit code; see Node.js exit codes.
FAQ
What value should I use for --max-old-space-size?
Leave headroom for the rest of the process and the system. On a machine or container with 2 GiB of memory, a common choice is about 1536 MiB; setting it higher than the available memory makes the operating system kill the process instead of V8 reporting an out-of-memory error.
Can I set the memory limit in package.json?
Not as a field. Put the flag in the script itself, for example node --max-old-space-size=4096 build.js, or set NODE_OPTIONS in the script with a cross-platform helper such as cross-env.
Does the flag fix a memory leak?
No. A bigger heap only delays the crash if memory keeps growing. Take heap snapshots (node --inspect, or --heapsnapshot-near-heap-limit) to find what is retained.