Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

davidconrad's avatar

MongoDB allowDiskUse on aggregation

I am trying to run an aggregation on a large data set. It is failing with a memory size error. As per mongoDB docs, I used the allowDiskUse option, and got the same error. Any ideas why this isn't working?

We are self hosted. (not using atlas)

mongodb 3.0.15

The query:

					$aggregationQuery = [
						[
							'$match' => [
								'$and' => [['startEpoch' => ['$gt' => $TimeRange]], ['client_id' => $client_id]],
							],
						],
						['$group' => ['_id' => '$' . $alert_category, 'totalPerDevice' => ['$sum' => 1]]],
					];

					$aggregations1 = LogicmonitorAlerts::raw(function ($collection) use ($aggregationQuery) {
						return $collection->aggregate($aggregationQuery, ['allowDiskUse' => true]);
					});

Error


PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in /usr/share/nginx/myha-v5/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Query/Builder.php on line 411

 Symfony\Component\ErrorHandler\Error\FatalError

  Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes)

  at vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Query/Builder.php:411
PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 266240 bytes) in /usr/share/nginx/myha-v5/vendor/nunomaduro/collision/src/Highlighter.php on line 134

0 likes
2 replies
LaryAI's avatar
Level 58

The error message suggests that the memory limit has been exceeded. To resolve this issue, you can try increasing the memory limit or using the allowDiskUse option in the aggregation query. However, it seems like the allowDiskUse option is not working in this case.

One possible solution is to split the aggregation into smaller chunks using the $skip and $limit operators. This will reduce the amount of data that needs to be processed at once and may help avoid the memory limit error.

Here's an example of how you can split the aggregation into smaller chunks:

$limit = 1000; // number of documents to process at once
$offset = 0; // starting offset

do {
    $aggregationQuery = [
        [
            '$match' => [
                '$and' => [['startEpoch' => ['$gt' => $TimeRange]], ['client_id' => $client_id]],
            ],
        ],
        ['$group' => ['_id' => '$' . $alert_category, 'totalPerDevice' => ['$sum' => 1]]],
        ['$skip' => $offset],
        ['$limit' => $limit],
    ];

    $aggregations1 = LogicmonitorAlerts::raw(function ($collection) use ($aggregationQuery) {
        return $collection->aggregate($aggregationQuery, ['allowDiskUse' => true]);
    });

    // process the results here

    $offset += $limit;
} while (count($aggregations1) > 0);

This code will process the aggregation in chunks of 1000 documents at a time, starting from the beginning of the result set and continuing until there are no more documents to process. You can adjust the $limit variable to control the size of each chunk.

Please or to participate in this conversation.