DEV Community

Cover image for Fixing "JavaScript heap out of memory" during production builds
Asta Silva
Asta Silva

Posted on

Fixing "JavaScript heap out of memory" during production builds

If you are running a large production build or a data-heavy script in Node.js, you have probably run into this crash:

Plaintext

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Enter fullscreen mode Exit fullscreen mode

The V8 stack trace that follows usually doesn't show the actual file or line causing the issue, making it difficult to debug.

Here is why this happens and how to fix it across your local environment, build scripts, and CI/CD pipelines.

Why This Happens

By default, the V8 engine limits the memory a single Node.js process can allocate. Depending on your Node version and system architecture, this limit defaults to roughly 1.5 GB or 4 GB.

This is usually fine for standard applications, but modern build tools (like Webpack, Vite, Next.js, or the TypeScript compiler) build large abstract syntax trees (AST) in memory. If your dependency graph or codebase grows past a certain size, the bundler hits the default allocation limit and crashes.

The Fix: Increase max-old-space-size

The direct solution is to instruct the V8 engine to allocate more memory using the --max-old-space-size flag (defined in megabytes).

Common allocation values

  • 4GB Allocation: --max-old-space-size=4096
  • 8GB Allocation: --max-old-space-size=8192

1. Temporary Local Environment Fix

To unblock your local machine for a single run, set the environment variable before your build command:

Bash

# Unix/macOS
NODE_OPTIONS="--max-old-space-size=4096" npm run build

# Windows (Command Prompt)
set NODE_OPTIONS=--max-old-space-size=4096 && npm run build

# Windows (PowerShell)
$env:NODE_OPTIONS="--max-old-space-size=4096"; npm run build
Enter fullscreen mode Exit fullscreen mode

2. Permanent Project Fix (package.json)

To ensure everyone on the team uses the same config, add it directly to your build scripts inside package.json. Use cross-env to avoid platform-specific syntax issues on Windows:

JSON

{
  "scripts": {
    "build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' next build",
    "compile": "cross-env NODE_OPTIONS='--max-old-space-size=4096' vite build"
  }
}
Enter fullscreen mode Exit fullscreen mode

Fixing the Error in CI/CD Pipelines

If your local builds pass but your deployment servers crash, you need to pass the memory variable to your runner or cloud provider.

GitHub Actions

Add the environment variable to your build step configuration:

YAML

- name: Run Production Build
  env:
    NODE_OPTIONS: --max-old-space-size=4096
  run: npm run build
Enter fullscreen mode Exit fullscreen mode

Docker Containers

Pass it as an environment parameter within your Dockerfile:

Dockerfile

FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN npm run build
Enter fullscreen mode Exit fullscreen mode

Managed Hosting (Vercel, Netlify, Cloudflare Pages)

  1. Go to your project settings dashboard.
  2. Open the Environment Variables tab.
  3. Add a new key: NODE_OPTIONS with the value --max-old-space-size=4096.
  4. Trigger a new deployment.

Checking for Underlying Problems

If you allocate 8GB or more of RAM and the build still fails, you are likely dealing with a memory leak or an infinite compilation loop rather than just a large codebase. Check these three areas:

Disable Source Maps in Production

Generating source maps for massive third-party dependencies takes a lot of memory. If your server is constrained, disable them in your config file to see if memory usage drops.

JavaScript

// next.config.js example
module.exports = {
  productionBrowserSourceMaps: false,
};
Enter fullscreen mode Exit fullscreen mode

Audit Circular Dependencies

Circular imports force compilers into recursive evaluation loops that drain memory. Use madge to audit your source directory for cyclical references:

Bash

npx madge --circular ./src
Enter fullscreen mode Exit fullscreen mode

Inspect the Runtime Heap

If the crash occurs on a running backend server rather than during a build script, you have a runtime leak (e.g., event listeners not being cleaned up, or global cache arrays growing indefinitely).

Start your server with the inspector flag enabled:

Bash

node --inspect index.js
Enter fullscreen mode Exit fullscreen mode

Open Chrome DevTools (chrome://inspect), target your Node process, and take a Heap Snapshot to see which objects are failing to garbage collect.

Top comments (0)