How do I determine the correct "max-old-space-size" for node.js?

209,446

Solution 1

"Old space" is the biggest and most configurable section of V8's managed (aka garbage-collected) heap (i.e. where the JavaScript objects live), and the --max-old-space-size flag controls its maximum size. As memory consumption approaches the limit, V8 will spend more time on garbage collection in an effort to free unused memory.

If heap memory consumption (i.e. live objects that the GC cannot free) exceeds the limit, V8 will crash your process (for lack of alternative), so you don't want to set it too low. Of course, if you set it too high, then the additional heap usage that V8 will allow might cause your overall system to run out of memory (and either swap or kill random processes, for lack of alternative).

In summary, on a machine with 2GB of memory I would probably set --max-old-space-size to about 1.5GB to leave some memory for other uses and avoid swapping.

Solution 2

2020 Update

These options are now documented officially by node. For a 2GB machine, you should probably use:

NODE_OPTIONS=--max-old-space-size=1536

To determine the amount to use

You can see available memory on a Linux machine using free -m. Note that you can consider the total of the free and the buffers/cache memory as available, as buffers/cache can be thrown away instantly when needed (these buffers and cache are a nice way to use otherwise unused memory).

The official documentation formax-old-space-size also mentions:

On a machine with 2GB of memory, consider setting this to 1536 (1.5GB)

Hence the value above. Consider that the amount of memory needed for the base OS doesn't change much, so you could happily do 3.5 on a 4GB machine etc.

To notice the defaults and see the effect of changes:

The default is 2GB:

$ node

> v8.getHeapStatistics()
{
  ....
  heap_size_limit: 2197815296,
}

2197815296 is 2GB in bytes.

When set to 8GB, you can see heap_size_limit changes:

$ NODE_OPTIONS=--max_old_space_size=8192 node
Welcome to Node.js v14.17.4.
Type ".help" for more information.
> v8.getHeapStatistics()
{
  ...
  heap_size_limit: 8640266240,
  ...
}

As @Venryx mentions below you can also use process.memoryUsage()

Solution 3

This error occurs when the memory allocated for the executing application is less than the required memory. By default, the memory limit in Node.js is 512 MB. To increase this amount, you need to set the memory limit argument —-max-old-space-size. It will help avoid a memory limit issue.

node --max-old-space-size=1024 index.js #increase to 1gb
node --max-old-space-size=2048 index.js #increase to 2gb
node --max-old-space-size=3072 index.js #increase to 3gb
node --max-old-space-size=4096 index.js #increase to 4gb
node --max-old-space-size=5120 index.js #increase to 5gb
node --max-old-space-size=6144 index.js #increase to 6gb
node --max-old-space-size=7168 index.js #increase to 7gb
node --max-old-space-size=8192 index.js #increase to 8gb

https://medium.com/@vuongtran/how-to-solve-process-out-of-memory-in-node-js-5f0de8f8464c

Share:
209,446

Related videos on Youtube

Borjante
Author by

Borjante

Passionate developer, currently in low performance mode.

Updated on January 11, 2022

Comments

  • Borjante
    Borjante over 2 years

    I'm having some trouble to understand how Node.js acts based on the parameter max-old-space-size.

    In my case, for example, I'm running two t2.small AWS instances (2GB of RAM).

    Not sure why, but I did set max-old-space-size=4096 (4GB). What does node do in this case? Could this configuration lead to a possible memory allocation failure?

    How do I determine the correct value of max-old-space-size based on the server resources?

    My application is constantly growing the memory usage and I'm trying to understand everything about node internals.

    • Borjante
      Borjante almost 6 years
      I'm adding a comment now that I see I that this is getting view quiete a lot. It took me a full week to realise that my NodeJS app had no memory leak but that the garbage collector never kicked in. Be aware of this on systems with low memory like t2.micro or t2.small instances. Server is going to crash because of non-available RAM.
    • gatlanticus
      gatlanticus over 4 years
      Was there a way to get the garbage collector to kick in?
    • divine
      divine over 4 years
      @Borjante why wasn't the garbage collector running?
    • Borjante
      Borjante over 4 years
      The configured max-old-space-size had a higher limit than the total amount of RAM that the machine had.
    • Constantinos
      Constantinos over 3 years
      Worth trying --optimize-for-size to reduce memory usage.
    • mikemaccana
      mikemaccana about 3 years
      @ZG101 To get the garbage collector to run, see stackoverflow.com/questions/27321997/…
  • Borjante
    Borjante over 6 years
    That's exactly what I was hoping to get for an answer, describing the edge case where either the system or Node runs out of memory.
  • Manish Trivedi
    Manish Trivedi almost 6 years
    @jmrk: Seems you are totally right, but when I am using 2GB RAM and 4GB swap and set "--max-old-space-size" to 4GB then node process consume all RAM memory and stuck on 1.9GB. The question is here "Why swap is avoid to use ?? " (Node version 8.11.1)
  • jmrk
    jmrk almost 6 years
    The flag should override anything else. Please double-check for typos.
  • jmrk
    jmrk about 5 years
    From d8 --help: --max-old-space-size (max size of the old space (in Mbytes))
  • HD..
    HD.. almost 4 years
    and it should be more than allocated Ram memory
  • JaySeeAre
    JaySeeAre almost 4 years
    I'm not sure this is true any more. Certainly on one system I have access to running node 10.20.1, I can see (with node --v8-options ) that the default reported is 4096 and without setting max-old-space-size the test suite i'm running gets up to 1.5Gb allocated with no trouble. The medium article linked is from 2016 so it is likely things have moved on since it was written.
  • JaySeeAre
    JaySeeAre almost 4 years
    It's difficult to find corroboration on that; I can't find anything explicit in the docs for V8 or Node. Another system I have reports the default for v10, 12 & 14. as 0. FWIW I have found a couple of more recent bloggers stating max memory as 1.5Gb (tejom.github.io/general/nodejs/v8/debugging/2017/01/16/…) and that v12 has a dynamic max based on the system (idginsiderpro.com/article/3257673/…).
  • JaySeeAre
    JaySeeAre almost 4 years
    node -e "console.log(`node heap limit = ${require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)" -> v12.18.0 and v14.3.0 -> 2096Mb, v10.20.1 -> 1432Mb
  • Sam Watkins
    Sam Watkins over 3 years
    @JaySeeAre, thanks for that command to show the heap_size_limit. For a normal UNIX shell, it needs to be quoted differently: node -e 'console.log(`node heap limit = ${require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'
  • JaySeeAre
    JaySeeAre over 3 years
    Ahh nice. thanks. yeah i probably should have said i was on windows. :)
  • Idan Dagan
    Idan Dagan over 3 years
    From the link you've shared from Node.js docs, it says: "On a machine with 2GB of memory, consider setting this to 1536 (1.5GB)"
  • mikemaccana
    mikemaccana over 3 years
    Thanks @IdanDagan I'll add that to the answer.
  • aerobrain
    aerobrain over 3 years
    I am using v12.16.3 --> 2096MB
  • jmrk
    jmrk about 3 years
    Nitpick: there is no reason to prefer a "round number" here. 1535 or 1537 or 1500 or 1555 are just as good.
  • mikemaccana
    mikemaccana about 3 years
    That's true - but since memory is in bytes, we're just picking an even quarter portion of those bytes (performance concepts like NUMA/cache coherancy aside).
  • Dilip Kumar Yadav
    Dilip Kumar Yadav almost 3 years
    which index.js file to be referred here.? Is it a project js file.?
  • Dilip Kumar Yadav
    Dilip Kumar Yadav almost 3 years
    I do not have index.js file in my project, somebody please help me out.
  • user2734550
    user2734550 over 2 years
    @JaySeeAre What does the heap_size_limit mean here? The total available memory that node could used up to?
  • Danubio Müller
    Danubio Müller over 2 years
    @JaySeeAre Yes, this is the total amount of memory that Node can depend on while running a script.
  • Venryx
    Venryx over 2 years
    As an alternative to v8.getHeapStatistics(), you can also use: process.memoryUsage() (as seen here)
  • ShortFuse
    ShortFuse about 2 years
    Example says --max_old_space_size, but docs says --max-old-space-size. Bad copy paste?
  • jmrk
    jmrk about 2 years
    @ShortFuse: both spellings work, you can use whichever you find easier to type.