Ffile2fix
Sign in Get started

How to fix "JavaScript heap out of memory" in Node.js

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

V8, Node's JavaScript engine, hit its maximum heap size and could not free enough memory by garbage collection, so the process aborted. Either the job genuinely needs more memory than the default limit, or something keeps holding on to memory (a leak or loading too much data at once).

Also appears as: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory · FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory · <--- Last few GCs ---> ... Mark-Compact (reduce) 2047.6 (2083.4) -> 2046.9 (2082.4) MB · npm run build exited with code 134 / Killed

Common causes

  • Large frontend builds (webpack, Vite, Next.js, Angular, TypeScript type-checking) exceeding the default heap on smaller machines
  • Reading an entire large file, query result or API response into memory instead of streaming it
  • A memory leak: caches, arrays or event listeners that grow forever in a long-running server
  • Building on a small VPS or CI runner with little RAM, where the OS kills the process or the heap limit is low
  • Recursive or runaway code creating objects in a loop

How to fix it

  1. Raise the heap limit for the command. Set NODE_OPTIONS=--max-old-space-size=4096 (in MB) before the command, e.g. NODE_OPTIONS=--max-old-space-size=4096 npm run build. Keep it below the machine's free RAM.
  2. Make it permanent for builds. Add the flag to the script in package.json or to your CI environment variables so every build gets the same limit.
  3. Check available RAM. Run free -m. If the server has 1-2 GB, add swap or build on your machine or in CI and deploy only the built files.
  4. Stream instead of loading everything. Use fs.createReadStream, streaming JSON/CSV parsers and database cursors for big data instead of readFileSync or one huge query.
  5. Find a leak in long-running apps. If memory climbs steadily over hours, start Node with --inspect, take heap snapshots in Chrome DevTools a few minutes apart and compare what keeps growing.
  6. Upgrade Node and tooling. Newer Node LTS versions and bundler releases use memory more efficiently; source maps and type-checking in the same process are common heavy hitters you can split out.

package.json

{
  "scripts": {
    "build": "node --max-old-space-size=4096 node_modules/vite/bin/vite.js build",
    "build:ci": "cross-env NODE_OPTIONS=--max-old-space-size=4096 next build"
  }
}

How to stop it happening again

  • Build assets in CI or locally rather than on small production servers
  • Stream large files and paginate database queries
  • Monitor process memory (pm2 monit, metrics) to catch leaks before they crash

Frequently asked questions

What is the default heap limit?

It depends on the Node version and available system memory; on modern 64-bit Node it is often around 2-4 GB, and less on low-memory machines or containers. --max-old-space-size overrides it.

Why does the build say 'Killed' with no heap error?

That is the Linux out-of-memory killer stopping Node because the whole server ran out of RAM. Raising the heap limit will not help; add RAM or swap, or build elsewhere.

How high should I set --max-old-space-size?

Set it to what the job needs and below the physical memory available, leaving room for the OS and other processes. 4096 is a common value for large frontend builds.