Skip to content
Monghoul

The 100 MB aggregation limit stopped failing your query in MongoDB 6.0

Most guides say a stage over 100 MB errors unless you pass allowDiskUse. That has been wrong since MongoDB 6.0, and the new failure is quiet.

· ·updated 13 September 2026 ·checked against MongoDB 6.0 and later
A row of vertical bars of varying height. A horizontal rule crosses near the top, two bars break above it, and an amber block sits below the baseline under each of those two.
Two stages exceed the budget. Since MongoDB 6.0 neither of them fails: both spill to disk and the query finishes, slowly.

Search for the 100 MB aggregation limit and you will find the same paragraph everywhere: a blocking stage that needs more than 100 MB of memory fails with QueryExceededMemoryLimitNoPersistenceAllowed unless you pass allowDiskUse: true.

That was true for years. It stopped being true in MongoDB 6.0, and the advice has outlived it because the failure it describes is loud and the behaviour that replaced it is quiet.

What changed

MongoDB 6.0 added a server parameter, allowDiskUseByDefault, and set it to true. A blocking stage that exceeds its memory budget now spills to disk on its own and the query completes.

So on 6.0 and later, the default behaviour is:

  • Before 6.0: the stage exceeds 100 MB, the query fails, you notice immediately.
  • 6.0 and later: the stage exceeds 100 MB, the query spills to disk, and it succeeds slowly.

Nothing errors. The pipeline that used to break now returns the right answer and takes long enough that somebody eventually opens a ticket about the page being slow.

Why this matters more than it sounds

An error tells you which query, which stage, and when. A spill tells you nothing unless you go looking. The pipeline still works in development, where the data is small enough to stay in memory, and degrades in production, where it is not. That is the same shape as most index problems and it is diagnosed the same way: by reading the plan rather than waiting for an exception.

explain("executionStats") reports spilling per stage. If a $group or $sort is writing to disk, that is where the time went.

The limit is per blocking stage, not per pipeline

This part is misreported almost as often. The budget applies to each stage that has to hold data, and only those stages:

$group, $sort, $bucket, $bucketAuto, $sortByCount, $setWindowFields.

Streaming stages buffer nothing, so $match, $project, $unwind and friends do not count against it. A pipeline with three blocking stages has three separate budgets rather than one shared 100 MB.

That also means “my pipeline uses more than 100 MB” is not by itself a problem. The question is whether any single blocking stage does.

If you would rather fail fast

Pass allowDiskUse: false explicitly. It restores the old behaviour for that one query, and there are good reasons to want it: an interactive endpoint that should return in 200 ms or not at all is better off erroring than spilling. Batch work usually wants the opposite.

db.collection('orders').aggregate(pipeline, { allowDiskUse: false });

The setting is per operation, so you can make an analytics job tolerant and keep a user-facing query strict, which is usually the right split.

What to do with older advice

Check the version before you follow it. If a page tells you to add allowDiskUse: true to fix an error, it was written for 5.0 or earlier, and on a current server it is a no-op that changes nothing because disk use was already allowed. The fix for a slow spilling stage is not a flag. It is an index that lets the sort use one, a $match earlier in the pipeline, or a smaller working set.

Which of those it is, the plan will tell you.