84

When I run "npm start" in application I get the following error - FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Most of the solutions posted online are about increasing memory with NODE_OPTIONS="--max-old-space-size=2048". But I have no idea where to set this. Some posts talked about a .bashrc file which my project does not have. I'm also on a windows system. The "npm start" command runs "npm run build-semantic && react-scripts start" as set up in package.json.

contrebis
  • 1,287
  • 1
  • 11
  • 20
Zephyr
  • 1,612
  • 2
  • 13
  • 37

12 Answers12

92

There could be multiple ways to use this flag. I'm using 8GB as an example to allocate the amount of memory but you could select as per your project.

First option

What OP was originally looking for was a way to set an Environment Variable. The NODE_OPTIONS --max-old-space-size environment variable allows to increase Node's max heap size. Setting an environmental variable allows Node to read this value from your environment and so we don't need to pass this value as an argument every time we run Node command. This is set as a global value and can be utilized by every Node process.

The process of setting an environment variable depends on the OS. Here are two SO posts on this:

In summary, set NODE_OPTIONS.

export NODE_OPTIONS="--max-old-space-size=8192"

If you put this command in the terminal session, you will need to do it in every new session. To avoid that, you can put that in the shell script file and the terminal will load it automatically for you.

The .bashrc file OP mentioned exists on Linux environment and most comments refer to reload the bash as a quick way like source ~/.bashrc which loads the env vars in the current session. One can always restart the terminal to reload but the former is mostly preferred! Again, ignore this if using Windows.

Second option

Now, if setting environment variable is not a preferred option, one can always use --max-old-space-size either while running the node command. Example from Nodejs.org documentation

$ node --max-old-space-size=8192 index.js

Third option

Alternatively, as the OP has already answered, we can set this per project basis but the implementation might vary depending on the project.

For npmscripts this Git comments answers it Best way to set --max-old-space-size when running npm (I reckon it's hyphens not underscore):

"scripts": 
{
    "start": "cross-env NODE_OPTIONS=--max-old-space-size=8192 webpack"
}

In Angular projects, you could define it like:

"scripts":
{
    "build-prod": "node --max-old-space-size=8192 ./node_modules/@angular/cli/bin/ng build --configuration=production"
}
sandiejat
  • 2,552
  • 19
  • 24
  • Is there anyway to get the old space param dynamically in package.json? I mean template like placeholder if we place in package.json automatic evaluation, is that possible and how ? – kernal_lora Feb 02 '21 at 03:04
  • the first option i would NOT recommand if this is on your main windows installation. I had side effects with other apps not opening like postman or whatsapp for instance. Better to set it at project level and not windows env level https://github.com/postmanlabs/postman-app-support/issues/6035 – Steven J Dec 24 '21 at 07:00
  • There are some cases where env vars could be a preferred (better) choice. Examples of such cases are - creating private base layer for containers or dedicated production build nodes. Keeping settings to the project level has its advantages obviously. – sandiejat Dec 24 '21 at 08:04
  • With second option I am getting error: <--- Last few GCs ---> <--- JS stacktrace ---> # # Fatal process OOM in insufficient memory to create an Isolate # – Dilip Kumar Yadav Jan 08 '22 at 13:02
  • @DilipKumarYadav Two things to note - did you use hyphens? For quite some time I used underscores mistakenly and never worked. Also, if the project is bigger, as in my case, I had to assign 10240 (10GB) for my build to succeed. There was no way around it. We had to upgrade to Angular13 and let go of some large libraries where tree shaking wasn't possible. – sandiejat Feb 07 '22 at 23:01
21

If you are on Unix then type

export NODE_OPTIONS=--max-old-space-size=<size in MB>

in the terminal.

If you are on windows then run

set NODE_OPTIONS=--max-old-space-size=<size in MB>
Bakr
  • 117
  • 8
Ashutosh dwivedi
  • 510
  • 3
  • 16
11

In your terminal type this:

export NODE_OPTIONS="--max-old-space-size=8192"
Matt
  • 33,328
  • 25
  • 83
  • 97
9

It's also possible to set NODE_OPTIONS in your .npmrc:

node-options=--max-old-space-size=8192
Big McLargeHuge
  • 14,841
  • 10
  • 80
  • 108
6

@Zephyr You can set the max value in your package.json

scripts": {
"start": "node  --max-old-space-size=1024 ./bin/www"
}

Also, you can even set the max size while starting you node application on through command line

node --max-old-space-size=1024 <path of your main file(For example server.js)>

Hope it helps :)

Gurpinder
  • 634
  • 1
  • 5
  • 18
4

The tricky thing here, is that you couldn't know how much memory will have on the production server, and limit the memory with a fixed value could be not the best option.

I wrote a code, to get the total memory on a linux machine, deduct 400mb (to other server resources), and assign it as node memory limit.

  FREE=$(free -m);
  echo "FREE: ${FREE}"
  FREE_FINAL=$(echo "$FREE" | grep -F Mem:  | grep -o "[0-9]*" | grep -o -m1 "^[0-9]*")
  echo "FREE_FINAL: ${FREE_FINAL}"
  MEM_LIMIT=$(($FREE_FINAL-400))
  echo "MEM_LIMIT: ${MEM_LIMIT}"
  echo " - "

  export MEMORY_LIMIT="${MEM_LIMIT:=3500}";

  export NODE_OPTIONS="--max-old-space-size=${MEMORY_LIMIT}"
  echo "NODE_OPTIONS: ${NODE_OPTIONS}"

You can create a build.sh or start.sh file, that will be called on package.json, to set the right limit.

If you use docker, it can be added to a entrypoint.sh file (that will run on build time, but on each docker start as well).

Tiago Gouvêa
  • 15,036
  • 4
  • 75
  • 81
4

I had some issues w/ setting this in the Windows 10 env vars as described in other answers and ended up using VSCode workspace settings instead:

  1. Create .vscode directory in your workspace
  2. Create settings.json inside .vscode directory with the following content:
{
  "terminal.integrated.env.windows": {
    "NODE_OPTIONS": "--max-old-space-size=8192"
  }
}

You can verify this in Powershell via: $env:NODE_OPTIONS

VSCode version: 1.62.3

Lars Gyrup Brink Nielsen
  • 3,939
  • 2
  • 34
  • 35
steve1337
  • 137
  • 1
  • 8
4

In case if you aren't familiar with the ways of Windows OS,

If you are a Windows user & are using the PowerShell instead of the Command Prompt, then Set NODE_OPTIONS="--max-old-space-size=8192" will not work. You need to use

$env:NODE_OPTIONS="--max-old-space-size=8192"

Note that the terminal in VSCode on Windows is also a PowerShell, so you might want to use this command instead.

Imal
  • 481
  • 1
  • 6
  • 14
3

This is what worked for me

My original package.json

"scripts": {
"start": "npm run build-semantic && react-scripts start"
}

Updated to

"scripts": {
"start": "npm run build-semantic && react-scripts start --max-old-space-size=1024"
}

Thanks @Gurpinder for the input

Zephyr
  • 1,612
  • 2
  • 13
  • 37
3

Some excellent answers here, but I just want to point out that if you're using Docker, in your Dockerfile, you can set your environment variable by including

ENV NODE_OPTIONS="--max-old-space-size=8192"

Just depends on what your setup is.

TheRealFakeNews
  • 7,512
  • 16
  • 73
  • 114
2

I was looking for something, to allocate max heap based on Kubernetes pod memory limit. landed here, so posting as an answer might help someone else.

          env:
            - name: MEMORY_LIMIT
              valueFrom:
                resourceFieldRef:
                  resource: limits.memory
            - name: NODE_OPTIONS
              value: "--max-old-space-size=$(MEMORY_LIMIT)"
Adiii
  • 54,482
  • 7
  • 145
  • 148
  • 1
    This is a good approach...I had to add `divisor: 1Mi`, maybe because I specified limits in `Mi` – James May 31 '23 at 13:57
  • This doesn't allow any memory for v8's --max-semi-space-size (default 16Mi) or the NodeJS process overhead of ~50Mi – Joe Bowbeer Jul 07 '23 at 06:22
0

On Windows 11 I had to set NODE_OPTIONS with —max-old-space-size=# in the system wide environment variables. My “npm run build” step executes webpack (Node 11.9.0) and would not honor the NODE_OPTIONS with any of the other suggestions here.

cchapin
  • 180
  • 1
  • 11