Download

MaxTimeMSExpired: operation exceeded time limit

The operation ran longer than the time limit it was given (maxTimeMS, set by your code, driver, ODM or a server default) and the server stopped it. Make it faster (an index, less data) or find what it waited for; raise the limit only if the time is expected.

MongoDB error 50· Tested on MongoDB 8.0.32 (mongosh 2.12.0)· Updated 11 October 2026

Executor error during find command: seo_err_mongo.events :: caused by :: operation exceeded time limit

What it means

maxTimeMS is a time limit, in milliseconds, that a client attaches to an operation. The server checks it while the operation runs, and when the time is up it stops the operation and returns code 50, MaxTimeMSExpired, with operation exceeded time limit. The limit counts the server’s processing time, added up across a cursor’s batches; network time and the time a cursor sits idle between batches don’t count.

The text before caused by says which operation it was: Executor error during find command: <db>.<collection> for a find, PlanExecutor error during aggregation for a pipeline. On its own (operation exceeded time limit) it often means the operation was waiting, for example for a lock held by a transaction.

Where the limit comes from:

  • Your code: .maxTimeMS(…) on a cursor, { maxTimeMS: … } on an aggregate or a write.
  • Your ODM or framework: Mongoose’s maxTimeMS() query option, or a default set in a library.
  • The server: on MongoDB 8.0 and later, the defaultMaxTimeMS cluster parameter sets a default for reads that don’t set their own.

Common causes

  1. A query without a useful index: a collection scan that took longer as the data grew.
  2. A heavy pipeline: $lookup without an index on the foreign field, $group or $sort over the whole collection, or a $regex that can’t use an index.
  3. Waiting for a lock: a write blocked by a document that an open transaction changed but hasn’t committed.
  4. A limit that’s too tight for an operation that is slow by nature, such as a report or an export.
  5. A busy or undersized server: everything is slower, and operations near their limit tip over.

How to fix it

See how long it takes, and why

Run it with explain("executionStats") (no time limit) and look at executionTimeMillis, totalDocsExamined and the plan’s stages:

db.events.find({ kind: 3 }).explain("executionStats").executionStats

COLLSCAN with totalDocsExamined far above nReturned means an index would help.

Add the index the query needs

db.events.createIndex({ kind: 1, placedAt: -1 })

Fields compared for equality go first, then the sort fields, then ranges.

Look for what it’s waiting on

While it runs, db.currentOp() shows each operation, how long it has run (secs_running) and whether it’s waiting for a lock (waitingForLock):

db.currentOp({ active: true, secs_running: { $gte: 1 } })

If writes wait on a transaction, find out why that transaction stays open, and keep transactions short.

Raise the limit only for slow-by-design work

db.events.aggregate(pipeline, { maxTimeMS: 120000 })

On MongoDB 8.0 and later, check whether the server sets a default for reads:

db.adminCommand({ getClusterParameter: "defaultMaxTimeMS" })

A maxTimeMS on the operation overrides it.

Reproduce it

MongoDB 8.0.32, mongosh 2.12.0, 5,000 documents and a filter that runs JavaScript ($where with a 10 ms sleep) to make the query slow:

db.events.find({ $where: "sleep(10); return true" }).maxTimeMS(100)
MongoServerError[MaxTimeMSExpired]: Executor error during find command: seo_err_mongo.events :: caused by :: operation exceeded time limit

The error’s code was 50 and its codeName MaxTimeMSExpired.

In a temporary single-member replica set of our own (mongo:8.0 --replSet rs0, removed afterwards), one session updated a document in a transaction and didn’t commit. A plain updateOne on the same document from another connection, with { maxTimeMS: 2000 }, waited and then failed after 2,038 ms:

MongoServerError[MaxTimeMSExpired]: operation exceeded time limit

After the transaction committed, the same update went through. A query stopped from outside with db.killOp() failed differently, with code 11601 (Interrupted): operation was interrupted after 214463 ms.

In Inlet

Queries use mongosh syntax, so .maxTimeMS(…) and explain("executionStats") work in a query tab, and a running query can be cancelled. When a query is refused or stopped, Inlet shows the server’s message.

Inlet: a database client for the Mac

One native app for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and Redis. It explains errors where they happen, holds your edits until you save them, and keeps production read-only until you say so.

Version 0.1.0 · macOS 26 Tahoe or later · Apple silicon and Intel