Skip to content

Conversation

@nexus-aissam
Copy link

Summary

When syncCollectionMethods (find, watch, aggregate) were called with a callback while buffering was enabled, the buffer timeout was never cleared after the operation completed successfully. This caused setTimeout references to accumulate in memory, leading to a memory leak.

The root cause was in lib/drivers/node-mongodb-native/collection.js lines 140-142, where the callback was not wrapped to call clearTimeout() - unlike all other buffered operation paths which properly clear the timeout.

Examples

Before this fix, the following code would leak memory:

const mongoose = require('mongoose');

// Connection not yet established - buffering enabled
const db = mongoose.createConnection();
const Model = db.model('Test', new mongoose.Schema({ name: String }));

// Each find() with callback creates a setTimeout that's never cleared
for (let i = 0; i < 1000; i++) {
  Model.find({}, (err, docs) => {
    // setTimeout reference leaks even after callback executes
  });
}

// Connect - operations execute but timeouts remain in memory
await db.openUri('mongodb://localhost/test');

After this fix, clearTimeout() is properly called when the operation completes, preventing the memory leak.

Fixes #15851

When syncCollectionMethods (find, watch, aggregate) were called with
a callback while buffering was enabled, the buffer timeout was never
cleared after the operation completed successfully. This caused
setTimeout references to accumulate, leading to a memory leak.

The fix wraps the callback to call clearTimeout() when the operation
completes, matching the behavior of all other buffered operation paths.

Fixes Automattic#15851
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

setTimeout memory leak in buffered operations

1 participant