Way to lower memory usage by mongoose when doing query Way to lower memory usage by mongoose when doing query mongodb mongodb

Way to lower memory usage by mongoose when doing query


Default mongoose .find() of course returns all results as an "array", so that is always going to use memory with large results, so this leaves the "stream" interface.

The basic problem here is that you are using a stream interface ( as this inherits from the basic node stream ) each data event "fires" and the associated event handler is executed continuosly.

This means that even with a "stream" your subsequent actions in the event handler are "stacking" up, at the very least consuming lots of memory and possibly eating up the call stack if there are further asynchronous processes being fired in there.

So the best thing you can do is start to "limit" the actions in your stream processing. This is as simple as calling the .pause() method:

var stream = model.find().stream();   // however you callstream.on("data",function() {    // call pause on entry    stream.pause();    // do processing    stream.resume();            // then resume when done});

So .pause() stops the events in the stream being emitted and this allows the actions in your event handler to complete before continuing so that they are not all coming at once.

When your handling code is complete, you call .resume(), either directly within the block as shown here of within the callback block of any asynchronous action performed within the block. Note that the same rules apply for async actions, and that "all" must signal completion before you should call resume.

There are other optimizations that can be applied as well, and you might do well to look a "queue processing" or "async flow control" available modules to aid you in getting more performance with some parallel execution of this.

But basically think .pause() then process and .resume() to continue to avoid eating up lots of memory in your processing.

Also, be aware of your "outputs" and similarly try to use a "stream" again if building up something for a response. All this will be for nothing if the work you are doing is just actually building up another variable in memory, so it helps to be aware of that.


You can use to use the lean option for a Mongoose query as long you only need plain JavaScript documents and not full Mongoose doc instances. This results in faster performance and reduced memory usage.

model.find().lean().exec(function(err, docs) {...});

You can also combine lean() with streaming the results which should reduce memory usage even further.

var stream = model.find().lean().stream();