Skip to content
MongoDB

MongoDB Error 50

operation exceeded time limit (MaxTimeMSExpired)

Applies to: MongoDB 7.0 and 8.0 (wording checked against the 8.0 source; defaultMaxTimeMS is new in 8.0)
Last technically reviewed 24 October 2026 on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally
The full message
MongoServerError: Executor error during find command: shop.orders :: caused by :: operation exceeded time limit
Other forms of this message
Without command context (other commands, or a timeout before execution starts)
operation exceeded time limit
While fetching a later batch of a cursor
Executor error during getMore :: caused by :: operation exceeded time limit
Error code
50
Code name
MaxTimeMSExpired
Product
MongoDB
Versions
MongoDB 7.0 and 8.0 (wording checked against the 8.0 source; defaultMaxTimeMS is new in 8.0)
Last reviewed
24 October 2026

What it means

Error 50 (MaxTimeMSExpired) means the operation ran longer than the time limit set with maxTimeMS (or the 8.0 defaultMaxTimeMS), so MongoDB stopped it and returned no further results.

maxTimeMS gives an operation a processing time budget in milliseconds. When the command starts, MongoDB 8.0 sets a deadline on the operation with code MaxTimeMSExpired; the operation checks for interruption as it works, and once the deadline has passed it stops with operation exceeded time limit. For find and getMore, the server adds the command context in front (Executor error during find command: <namespace> :: caused by :: ...). MongoDB documents that it ends such operations the same way as killOp, only at designated interrupt points, and that network latency between client and server does not count (on a sharded cluster the mongos to shard latency does).

For a cursor the limit is cumulative across the batches it processes, not per batch, and idle time between getMore calls does not count. The limit can come from your code (.maxTimeMS() or a driver option), from an ODM default, or, from MongoDB 8.0, from the defaultMaxTimeMS cluster parameter, which applies to find, aggregate (without $out or $merge), count, distinct and dbHash when the operation sets no maxTimeMS itself. The same text is used with code 262 ExceededTimeLimit for other internal deadlines, so check the code, not only the message.

Common causes

  • The query has no suitable index and scans the whole collection (COLLSCAN), or sorts many documents in memory.
  • The limit is too small for a legitimate operation: a report or export run with the timeout meant for interactive queries.
  • A defaultMaxTimeMS cluster parameter (MongoDB 8.0) applies to read operations that were never written with a limit in mind.
  • An ODM or driver option sets maxTimeMS on every operation without the developer realising it.
  • The server is overloaded or the operation waits a long time (locks, a pending DDL operation), so time runs out before it finishes.
  • A cursor is iterated over a very large result, and the cumulative processing time of its batches exceeds the limit.

Diagnose it

Read-only These mongosh commands only read data, indexes, statistics and server state (find, aggregate without $out or $merge, getIndexes, stats, currentOp, rs.status). They do not change data, users or settings, so they are safe to run first.

See how the query is executed

db.orders.find({ customerId: 4211, status: "open" })
  .sort({ createdAt: -1 })
  .explain("executionStats")
What to look for

In queryPlanner.winningPlan, a COLLSCAN stage or an in-memory SORT stage points at a missing index. In executionStats, compare totalDocsExamined with nReturned and read executionTimeMillis. Explain with executionStats runs the query, so give it a modest limit on very large collections.

List the indexes on the collection

db.orders.getIndexes()
What to look for

The existing index keys. A compound index whose fields match the query's equality filters first, then the sort, then range filters, usually removes both the scan and the in-memory sort.

Find slow operations that are running now

db.getSiblingDB("admin").aggregate([
  { $currentOp: { allUsers: true } },
  { $match: { active: true, secs_running: { $gte: 5 } } },
  { $project: { opid: 1, ns: 1, secs_running: 1, planSummary: 1, command: 1 } }
])
What to look for

Operations running for 5 seconds or more, with their planSummary (for example COLLSCAN or IXSCAN { status: 1 }). These are the ones most likely to reach a time limit.

Check whether a cluster-wide default applies (MongoDB 8.0)

db.adminCommand({ getClusterParameter: "defaultMaxTimeMS" })
What to look for

readOperations is the default limit in milliseconds; 0 means no default. A non-zero value explains timeouts on reads that set no maxTimeMS themselves.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Add an index that supports the query

Changes schema

Most MaxTimeMSExpired errors on normal queries disappear when the query can use an index. Order the keys as equality fields, then the sort field, then range fields.

Caution: Building an index on a large collection uses CPU, I/O and memory on every replica set member. Build it at a quiet time and check free disk space first.

db.orders.createIndex({ customerId: 1, status: 1, createdAt: -1 })

Return less: filter, project and paginate

Client or network side

Ask for fewer documents and fields. Use a projection, a limit, and range-based pagination on an indexed field instead of large skip values.

db.orders.find(
  { customerId: 4211, createdAt: { $lt: lastSeenCreatedAt } },
  { _id: 1, total: 1, createdAt: 1 }
).sort({ createdAt: -1 }).limit(50)

Give a long operation its own, deliberate limit

Client or network side

For a known slow operation such as a report, set a larger maxTimeMS on that operation only. MongoDB's defaultMaxTimeMS documentation recommends exactly this for analytics queries, since an operation-level maxTimeMS overrides the default.

db.orders.aggregate(
  [ { $match: { createdAt: { $gte: ISODate("2026-01-01") } } },
    { $group: { _id: "$status", total: { $sum: "$total" } } } ],
  { maxTimeMS: 120000 }
)

Adjust the cluster default only after review (MongoDB 8.0)

Changes configuration

If defaultMaxTimeMS is too low for the normal workload, a user with clusterAdmin can change it. Prefer fixing the slow queries first.

Caution: This changes the limit for every read on the cluster that does not set its own maxTimeMS. Raising it lets runaway queries run longer; lowering it can break existing reports. Agree the value with the application owners.

db.adminCommand({
  setClusterParameter: { defaultMaxTimeMS: { readOperations: 10000 } }
})

Examples

An unindexed query with a 100 ms limit

Not reproduced here: no MongoDB server is installed for this site. The wording is built by MongoDB 8.0's source: the base text in operation_context.cpp (checkForInterruptNoAssert) and the find context added in find_cmd.cpp, with this example's namespace (database shop). Whether a given query reaches the limit depends on the data size and hardware.

db.orders.find({ note: /refund/i }).maxTimeMS(100).toArray()
Expected result (documented format, not run)
MongoServerError: Executor error during find command: shop.orders :: caused by :: operation exceeded time limit

A cursor that runs out of time on a later batch

Not reproduced here: no MongoDB server is installed for this site. MongoDB's cursor.maxTimeMS() documentation describes the cumulative limit; the wording is the getMore context from MongoDB 8.0's getmore_cmd.cpp around the same base text. The values are illustrative.

const cur = db.events.find({ type: "click" }).maxTimeMS(2000).batchSize(1000)
while (cur.hasNext()) { cur.next() }   // the limit is cumulative over all batches
Expected result (documented format, not run)
MongoServerError: Executor error during getMore :: caused by :: operation exceeded time limit

How to prevent it

Check the explain plan of every frequent query during development, create indexes for them, and keep interactive and reporting workloads on different time limits (and, where possible, on different nodes).

Set time limits deliberately in one place in the application, log the code (50) and the query shape whenever one is hit, and review the slowest operations regularly with the profiler or the slow query log.

Common questions

How do I fix "operation exceeded time limit" in MongoDB?

Run the query with explain("executionStats"). If it scans the collection or sorts in memory, add a matching index. If the operation is legitimately long, set a larger maxTimeMS on that operation only.

I never set maxTimeMS. Where does the limit come from?

From the driver or ODM configuration, from the Node.js driver timeoutMS option (which takes precedence over maxTimeMS), or on MongoDB 8.0 from the defaultMaxTimeMS cluster parameter. Check getClusterParameter and your client settings.

What is the difference between error 50 and error 262?

Both use the text operation exceeded time limit. 50 MaxTimeMSExpired is for the maxTimeMS limit of your operation; 262 ExceededTimeLimit is used for other internal deadlines. Check the code to know which one you have.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally. Codes and code names are checked against MongoDB's error_codes.yml (8.0); no MongoDB server was available, so the examples were not run locally.

Still stuck on a MongoDB error?

Browse the full MongoDB error library, or get hands-on help from an experienced SQL professional.