← Debugging Guides

阅读中文版本

MongoDB: connection pool timeout waiting for available connection

Fix MongoDB connection pool timeouts by sizing maxPoolSize, finding connection leaks, and matching pool size to workload concurrency.

intermediatedebuggingmongodbdatabaseconnection-pool

Symptoms

  • MongoServerSelectionError or MongoWaitQueueTimeoutError: Timed out while waiting for a connection
  • Requests queue under load and then fail
  • The driver logs wait queue timeouts only at peak

Possible causes

  • maxPoolSize is smaller than the concurrent operation count
  • Connections are checked out and not released due to a leaked cursor or session
  • A slow query holds a connection for a long time
  • Many application instances multiply the total demand against the server limit

Diagnosis steps

Check pool metrics and wait queue times

client.on("connectionPoolCreated", ...) and pool stats

Interpretation

Consistently waiting for a connection means the pool is saturated.

Look for operations that never complete

Interpretation

A leaked cursor or uninterruptible query holds a connection indefinitely.

Compare total connections across instances to the server limit

Interpretation

Many instances each with a large pool can exceed maxIncomingConnections on the server.

Root cause

The driver maintains a connection pool; an operation checks out a connection and returns it when done. If the pool is smaller than the number of simultaneous operations, waiters time out. Leaked connections or slow operations make the pool effectively smaller.

Fix

Increase maxPoolSize to match concurrent demand, and ensure cursors, sessions, and transactions are closed so connections return to the pool. Optimise slow queries that hold connections, and account for the total across instances so the aggregate stays under the server connection limit.

Verify the fix

Re-run the load; wait queue timeouts disappear, pool statistics show connections cycling rather than pinned, and p95 latency stays stable.

Symptoms

Under load the driver reports Timed out while waiting for a connection or a server selection error. It clears when traffic drops, which marks a pool sizing or leak problem.

Diagnosis

Watch pool events and size against concurrency:

const client = new MongoClient(uri, {
  maxPoolSize: 50,
  waitQueueTimeoutMS: 5000,
});
client.on('connectionPoolCreated', (e) => console.log(e));

If waiters always exceed free connections, the pool is too small or connections are pinned.

Fix

Size the pool and release resources:

const cursor = coll.find({});
for await (const doc of cursor) { /* ... */ }
await cursor.close();          // return the connection
await session.endSession();    // close sessions

Keep the aggregate maxPoolSize * instances under the server limit.

Verification

Re-run the load test; pool stats show connections returning, wait-queue timeouts stop, and latency remains stable instead of climbing then failing.

Additional Notes

Pool exhaustion is often a symptom of operations that never release their connection rather than of genuinely insufficient capacity. Cursors, sessions, and transactions each borrow a connection, and one left open holds it for the life of the process. Comparing active connections to in-flight operations reveals whether the pool is truly undersized or merely leaking, and combining pool size across every application instance against the server limit avoids a different failure where the aggregate exceeds what the server accepts. Wait-queue timeouts are the clearest signal that demand outstrips capacity.