7

I been noticing that our node app runs out of memory after a day or so. The memory is consumed by a job that runs every minute or so, because that is pretty much the only thing going on right now. When I run the app locally on my machine I can the see the app hitting the memory ceiling as well and then garbage collection jumps in.

On heroku it seems go beyond the memory ceiling of our 1G RAM instance and the GC isn't kicking in. I wonder if that is because node is configured with a higher memory limit then actual Dyno.

Rephrase: Is node.js memory limit on herkou bound to the Dyno memory limit?

1
  • Have you asked Heroku how their system works?
    – womble
    Aug 17, 2015 at 0:06

1 Answer 1

6

Here is the response from heroku. Looks like you need to make configuration changes and can't use the out of the box config.

Hi Stan,

Thanks for linking to those docs; I'll need to update that terminal example as I've recently silenced the chatty WEB_CONCURRENCY output. We added logging when we added the feature largely so folks wouldn't be surprised at these new variables invading their environment.

To see the values for your app, you can run:

$ heroku run 'echo $WEB_MEMORY, $WEB_CONCURRENCY' However, let me be clear - these values only exist for determining how many concurrent processes should be run by a clustered node app, and even then only if you choose to use the WEB_CONCURRENCY value in your code. They do not impact, at all, the node binary or its default memory allocations or garbage collection, which are totally standard, vanilla versions downloaded from nodejs.org/dist:

https://devcenter.heroku.com/articles/node-concurrency#tuning-the-concurrency-level V8 uses a greedy and lazy approach to garbage collection. Additionally, V8 assumes by default that you have about 1.5 GB to work with (more than the 1 GB limit of a 2X dyno). You have a few options if you're interested in changing node's default memory behavior:

  • Manually trigger GC whenever memory exceeds a set limit (https://simonmcmanus.wordpress.com/2013/01/03/forcing-garbage-collection-with-node-js-and-v8/)

  • Set max_old_space_size to lower than the default (eg, node --max_old_space_size=960). Several metrics in the v8 source are tied to max_old_space_size, so this can make gc somewhat more aggressive. The downside is that if you exceed the value even by a byte, your program will crash.

  • Set gc_global to true to force always-global collection (false by default - keep in mind that global collection is slower than the default multi-phase collection).

  • Set nolazy_sweeping to true, which also makes the gc a little more aggressive.

Keep in mind that, if you're exceeding about 1 GB of memory in a single node process, the best practice is to split that process into multiple workers:

https://github.com/joyent/node/wiki/FAQ#what-is-the-memory-limit-on-a-node-process Cheers, Hunter

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .