Introduction

MongoDB connection pool runs out of available connections, preventing new connections from being established. Applications fail with connection errors while the pool shows all connections are in use.

Symptoms

Connection pool exhausted:

```bash # Application error: MongoError: Connection pool for "mongodb://localhost:27017" exhausted

# MongoDB driver error: MongoTimeoutError: Connection pool exhausted, waiting for available connection timed out after 30000ms ```

Server logs:

```bash $ mongod --logpath /var/log/mongodb/mongod.log

[conn1234] connection refused because too many open connections: 819 ```

Connection statistics:

```javascript > db.serverStatus().connections

{ "current" : 1000, "available" : 0, "totalCreated" : 5000 } // available = 0 means pool exhausted ```

Common Causes

  1. 1.Pool size too small - Not enough connections for workload
  2. 2.Connection leaks - Connections not returned to pool
  3. 3.Long-running queries - Connections held too long
  4. 4.Insufficient timeout - Connections not timing out
  5. 5.Max connections reached - Server limit hit
  6. 6.Connection storm - Sudden spike in concurrent requests

Step-by-Step Fix

  1. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 6.Verify the fix

Step 1: Check Current Connection Status

```javascript // Check server connection stats db.serverStatus().connections

// Check connection pool stats (driver-specific) db.serverStatus().metrics.connection

// Count active connections by client db.currentOp({"active": true}).inprog.forEach(function(op) { print(op.client + " - " + op.active); })

// Check connection source db.currentOp().inprog.forEach(function(op) { if (op.client) print(op.client); })

// List all connections (admin) db.adminCommand({currentOp: 1, "$all": true})

// Check for idle connections db.currentOp({"active": false})

// Server status with connection details db.serverStatus({connections: 1, metrics: 1}) ```

Step 2: Check Pool Configuration

```javascript // Connection pool settings in driver:

// Node.js (mongodb driver): const client = new MongoClient(uri, { maxPoolSize: 100, // Maximum connections in pool minPoolSize: 10, // Minimum connections maintained maxIdleTimeMS: 60000, // Close idle connections after 60s waitQueueTimeoutMS: 30000, // Wait timeout for connection connectTimeoutMS: 30000, // Connection timeout socketTimeoutMS: 30000 // Socket timeout });

// Java driver: MongoClientSettings settings = MongoClientSettings.builder() .applyToConnectionPoolSettings(builder -> builder .maxSize(100) .minSize(10) .maxWaitTime(30, TimeUnit.SECONDS) .maxConnectionIdleTime(60, TimeUnit.SECONDS) .maxConnectionLifeTime(30, TimeUnit.MINUTES)) .build();

// Python (pymongo): client = MongoClient(uri, maxPoolSize=100, minPoolSize=10, maxIdleTimeMS=60000, waitQueueTimeoutMS=30000, connectTimeoutMS=30000, socketTimeoutMS=30000 ) ```

Step 3: Check Server Connection Limits

```bash # Check MongoDB max connections mongo --eval "db.serverStatus().connections"

# Check configured limit mongod --setParameter maxConns=1000

# Or in mongod.conf: net: maxIncomingConnections: 1000

# Check ulimit for MongoDB process cat /proc/$(pgrep mongod)/limits | grep "open files"

# Check system file descriptor limit ulimit -n

# Increase ulimit: # In /etc/security/limits.conf: mongodb soft nofile 65536 mongodb hard nofile 65536

# Or in mongod service file: [Service] LimitNOFILE=65536 ```

Step 4: Identify Connection Leaks

```javascript // Check for connections not being closed

// Common leak patterns:

// WRONG: Connection not closed async function query() { const client = new MongoClient(uri); await client.connect(); const result = await client.db().collection('users').find({}).toArray(); return result; // client.close() never called! }

// CORRECT: Always close connections async function query() { const client = new MongoClient(uri); try { await client.connect(); return await client.db().collection('users').find({}).toArray(); } finally { await client.close(); } }

// BETTER: Use connection pooling (singleton client) let cachedClient = null;

async function getClient() { if (!cachedClient) { cachedClient = new MongoClient(uri); await cachedClient.connect(); } return cachedClient; }

// Use withConnect wrapper const { withTransaction } = require('mongodb');

await withTransaction(client, async (session) => { // Transaction work }); ```

Step 5: Monitor Connection Pool

```javascript // Enable connection pool monitoring (Node.js driver) const client = new MongoClient(uri, { maxPoolSize: 100 });

// Monitor pool events client.on('connectionPoolCreated', (event) => { console.log('Pool created:', event); });

client.on('connectionCreated', (event) => { console.log('Connection created:', event.address); });

client.on('connectionReady', (event) => { console.log('Connection ready:', event.address); });

client.on('connectionClosed', (event) => { console.log('Connection closed:', event.address, event.reason); });

client.on('connectionCheckOutStarted', (event) => { console.log('Checking out connection'); });

client.on('connectionCheckOutFailed', (event) => { console.error('Checkout failed:', event.reason); });

client.on('connectionCheckedOut', (event) => { console.log('Connection checked out:', event.connectionId); });

client.on('connectionCheckedIn', (event) => { console.log('Connection checked in:', event.connectionId); });

// Get pool size metrics db.serverStatus().metrics.connection ```

Step 6: Fix Long-Running Queries

```javascript // Identify long-running operations db.currentOp({ "active": true, "secs_running": {"$gt": 30} })

// Kill long-running operations db.killOp(opId)

// Check slow queries db.system.profile.find({ millis: {$gt: 10000} }).sort({ts: -1}).limit(10)

// Enable profiling db.setProfilingLevel(1, { slowms: 1000 })

// Add query timeout db.collection.find({}).maxTimeMS(30000)

// Add index to improve query speed db.collection.createIndex({field: 1}) ```

Step 7: Configure Connection Timeouts

```javascript // Proper timeout configuration

const client = new MongoClient(uri, { // Connection timeouts connectTimeoutMS: 30000, // Time to establish connection socketTimeoutMS: 30000, // Time for socket operations

// Pool timeouts waitQueueTimeoutMS: 30000, // Time to wait for available connection maxIdleTimeMS: 60000, // Close idle connections after 60s maxConnectionLifeTimeMS: 1800000, // Close connections after 30 min

// Heartbeat heartbeatFrequencyMS: 10000, // Check connection health every 10s

// Pool sizing maxPoolSize: 100, minPoolSize: 10 });

// Server-side timeout configuration (mongod.conf): setParameter: cursorTimeoutMillis: 600000 maxTimeDefaultTimeLimit: 60000 ```

Step 8: Implement Connection Pooling Best Practices

```javascript // 1. Use a single MongoClient instance (connection pooling is per-client) // Global client instance let dbClient = null;

async function getDb() { if (!dbClient) { dbClient = new MongoClient(process.env.MONGODB_URI, { maxPoolSize: 50, minPoolSize: 10 }); await dbClient.connect(); } return dbClient.db(); }

// 2. Handle graceful shutdown process.on('SIGINT', async () => { if (dbClient) { await dbClient.close(); } process.exit(0); });

// 3. Use connection pooling for serverless // For AWS Lambda, use global client with lazy initialization let client = null;

exports.handler = async (event) => { if (!client) { client = new MongoClient(uri, { maxPoolSize: 10, minPoolSize: 0, maxIdleTimeMS: 60000 }); await client.connect(); } // Process event };

// 4. Monitor pool health setInterval(() => { const poolStats = client.db().admin().serverStatus().connections; console.log(Connections: ${poolStats.current}/${poolStats.current + poolStats.available}); }, 60000); ```

Step 9: Handle Connection Errors

```javascript // Robust connection handling with retry

async function connectWithRetry(uri, options = {}, maxRetries = 3) { let lastError;

for (let i = 0; i < maxRetries; i++) { try { const client = new MongoClient(uri, { ...options, serverSelectionTimeoutMS: 5000, connectTimeoutMS: 10000 }); await client.connect(); console.log('Connected to MongoDB'); return client; } catch (error) { lastError = error; console.error(Connection attempt ${i + 1} failed:, error.message); await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } }

throw lastError; }

// Handle connection loss client.on('serverClosed', (event) => { console.log('Server closed, attempting reconnect'); });

// Use retryable reads/writes const client = new MongoClient(uri, { retryWrites: true, retryReads: true }); ```

Step 10: Monitor and Alert on Pool Exhaustion

```javascript // Create monitoring script const monitor = setInterval(async () => { try { const status = await db.admin().serverStatus(); const connections = status.connections;

const utilization = connections.current / (connections.current + connections.available);

console.log({ current: connections.current, available: connections.available, utilization: (utilization * 100).toFixed(1) + '%' });

// Alert if utilization high if (utilization > 0.8) { console.error('WARNING: Connection pool utilization > 80%'); // Send alert }

if (connections.available === 0) { console.error('CRITICAL: Connection pool exhausted'); // Send critical alert } } catch (error) { console.error('Monitoring error:', error); } }, 30000);

// Prometheus metrics // mongodb_connections{state="current"} // mongodb_connections{state="available"} // mongodb_connection_pool_utilization ```

MongoDB Connection Pool Checklist

CheckCommandExpected
Pool sizedriver configSufficient for load
ConnectionsserverStatus()current < max
Leakscode reviewConnections closed
Timeoutsdriver configReasonable values
Server limitmongod.conf> pool max
Long queriescurrentOpNone > 30s

Verification

```bash # After fixing connection pool issues

# 1. Check available connections mongo --eval "db.serverStatus().connections" // available > 0

# 2. Monitor pool utilization mongo --eval "db.serverStatus().connections" // current / (current + available) < 0.7

# 3. Test application connectivity node test_connection.js // Successfully connects

# 4. Run load test # Check connections stay within limits

# 5. Check for connection leaks over time # Monitor current connections shouldn't grow unbounded

# 6. Verify timeout handling # Connections returned to pool after idle time ```

Prevention

To prevent MongoDB connection pool exhaustion from recurring, implement these proactive measures:

1. Configure Appropriate Pool Sizes

javascript
const client = new MongoClient(uri, {
  maxPoolSize: 100,
  minPoolSize: 10,
  maxIdleTimeMS: 60000,
  waitQueueTimeoutMS: 5000,
  connectTimeoutMS: 30000,
});

2. Monitor Connection Pool Metrics

yaml
groups:
- name: mongodb-connections
  rules:
  - alert: MongoDBConnectionPoolNearCapacity
    expr: |
      mongodb_connections{state="current"} / mongodb_connections{state="available"} > 0.8
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "MongoDB connection pool at 80% capacity"

3. Implement Connection Pool Management

```javascript // Use singleton pattern for connection management class MongoConnectionManager { constructor(uri, options) { this.client = new MongoClient(uri, options); }

async getConnection() { if (this.client.isConnected()) { return this.client.db(); } return this.client.connect().then(() => this.client.db()); }

async close() { await this.client.close(); } } ```

4. Configure Server Limits

```bash # In mongod.conf: net: maxIncomingConnections: 10000

# Set ulimit for MongoDB process LimitNOFILE=64000 ```

Best Practices Checklist

  • [ ] Configure pool size based on expected load
  • [ ] Monitor pool utilization with alerts
  • [ ] Use connection pool singleton pattern
  • [ ] Set appropriate MongoDB server limits
  • [ ] Run regular connection health checks
  • [ ] Test connection behavior under load
  • [Fix MongoDB Connection Timeout](/articles/fix-mongodb-connection-timeout)
  • [Fix MongoDB Slow Query Performance](/articles/fix-mongodb-slow-query-performance)
  • [Fix MongoDB Replica Set Primary Not Found](/articles/fix-mongodb-replica-set-primary-not-found)
  • [WordPress troubleshooting: Fix aggregation pipeline memory limit ex](aggregation-pipeline-memory-limit-exceeded-group)
  • [Technical troubleshooting: Fix capped size limit insert failing Issue in Mong](capped-size-limit-insert-failing)
  • [Technical troubleshooting: Fix change stream resume token expired event loss ](change-stream-resume-token-expired-event-loss)
  • [Technical troubleshooting: Fix chunk migration failed shard key cardinality I](chunk-migration-failed-shard-key-cardinality)
  • [Fix connection string srv record not resolving Issue in Mongodb-Errors](connection-string-srv-record-not-resolving)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix MongoDB Connection Pool Exhausted", "description": "Troubleshoot MongoDB connection pool exhausted. Check pool size, leaks, timeout settings.", "url": "https://www.fixwikihub.com/fix-mongodb-connection-pool-exhausted", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-05T06:30:26.368Z", "dateModified": "2026-04-05T06:30:26.368Z" } </script>