The operations are those of CRUD Operations to The Aggregation Pipeline; what changes in a server process is volume. Two driver mechanics carry it: bulkWrite turns many writes into few commands, and a cursor streams results in batches.
const sales = client.db("shop").collection("sales");
const regions = ["north", "south", "east", "west"];
const t0 = Date.now();
for (let b = 0; b < 10; b++) // 10 commands, 5,000 documents each
await sales.bulkWrite(Array.from({ length: 5000 }, (_, i) => ({ insertOne: { document: {
order: b * 5000 + i, region: regions[i % 4], total: ((b * 7 + i) % 900) + 100 } } })),
{ ordered: false });
console.log("loaded", await sales.estimatedDocumentCount(), "docs in", Date.now() - t0, "ms");
let n = 0, sum = 0;
const cursor = sales.find({ total: { $gt: 500 } }, { batchSize: 1000 });
for await (const doc of cursor) { n += 1; sum += doc.total; }
console.log(n, "docs, mean", Math.round(sum / n), "| cursor closed:", cursor.closed);
for (const r of await sales.aggregate([{ $group: { _id: "$region", rev: { $sum: "$total" } } },
{ $sort: { rev: -1 } }, { $limit: 2 }]).toArray()) console.log(r._id, r.rev);loaded 50000 docs in 998 ms 26255 docs, mean 741 | cursor closed: true west 6662250 east 6658750
find and aggregate are lazy: they build a cursor and send nothing until you iterate, so find() never throws — the error arrives at the first next, toArray or for await. Iterating with for await fetches one batch per round trip and yields documents one at a time; these 50,000 documents cost 105 MB of heap through toArray and 26 MB through for await, because only a batch is resident. Raise batchSize to trade memory for round trips, and always finish or close a cursor: an abandoned one holds server resources until cursorTimeoutMillis (600,000 ms by default). To pipe results into a file or a response, cursor.stream() gives a Node readable stream with real backpressure (Node.js). Keep bulkWrite batches at a few thousand operations: a command may carry 100,000 writes and 48 MB, but small batches keep memory flat and give you a point to log progress from.