Increasing Node.js Memory Limit

When keeping a large amount of data in memory (as in, ≥ ~1.4GB) you will probably hit the default limit for the old generation space in the heap, FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory. A quick and dirty workaround is to manually increase the limit with e.g., --max-old-space-size=8192 to buy some time while you rethink your approach.

In a generational garbage collector, like the one used by V8, the heap is usually divided in two major spaces: a young generation (new-space in V8) and an old generation (old-space in V8).

This division comes from the observation that only around 20% of the objects that are allocated are long-lived, the rest are used only a few times and can be deallocated shortly after creation. On the other hand, objects that survive and are moved to the old generation are likely to stay there for the duration of the execution.

The young generation is small (around 1-8MB) and consequently fast to scan and garbage collect. The few objects that survive 1-2 runs of the garbage collector are eventually moved to the old generation, which is much larger at about 1.4GB by default. As few objects make it to the old generation and as it is much bigger, garbage collection in the old space, although more expensive, is infrequent.

It is only when this bigger old-space gets full and there are no objects that can be swept to free up memory that you start encountering memory allocation problems, e.g., FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory.

The short term work-around is to increase the old-generation by passing the option --max-old-space-size=8192 (amount is in MB, so 8GB in this example), however the root cause is probably a bad architecture (or a memory leak).

The real solution is likely to involve replacing some load all the data and then process it pattern with a streaming approach. This applies, of course, to loading results from a database query. Use pagination if the results are to be displayed in a user interface or streaming if you need to process them all in some cron job.