MySQL connection pool exhaustion: find the leak or the wait
Too many connections is an outcome of saturation, leaks, or slow transactions. Identify which clients hold connections before increasing capacity.
Maintained by Kevin · Ovalk
Scope and prerequisites
MySQL 8.x. Managed databases may restrict administrative commands and expose metrics through their console.
Use an approved database connection without putting passwords in shell history. Viewing other users' sessions needs suitable privileges. Record application replica counts and pool limits.
Common symptoms
- Applications return Too many connections.
- The database accepts no new sessions even though CPU is not necessarily high.
- Sleep sessions or long-running transactions do not fall after traffic subsides.
1. Classify the connection growth
Compare current and maximum connections, then group sessions by user, host and command. Connections that remain high after a traffic drop point to pool return, transaction cleanup, or eviction behavior.
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
mysql -e "SELECT USER,HOST,COMMAND,COUNT(*) c FROM performance_schema.processlist GROUP BY 1,2,3 ORDER BY c DESC;"2. Identify the work holding sessions
Use a process-list snapshot with slow-query logs and request traces. Do not kill sessions in bulk before identifying ownership, particularly where writes may still be in flight.
mysql -e "SELECT ID,USER,HOST,DB,COMMAND,TIME,STATE,LEFT(INFO,160) FROM performance_schema.processlist WHERE COMMAND <> 'Sleep' ORDER BY TIME DESC;"3. Restore capacity safely
Reduce nonessential traffic or roll unhealthy clients first. Increase max_connections only after calculating per-connection memory and the aggregate pool budget across every application instance.
mysql -e "SHOW ENGINE INNODB STATUS\G"Interpret the evidence
| Observation | What to check next |
|---|---|
| Many Sleep sessions | Idle pooled connections can be normal. Correlate with configured pool size and open transactions before calling this a leak. |
| Pool wait rises; connected sessions stay near the limit | Reduce arrival pressure and find the work holding connections. More connections can increase contention. |
| Only one database user grows | Trace that user's application instances and deployments; take successive snapshots to distinguish growth from a stable pool. |
Illustrative diagnosis
A hypothetical example to explain the reasoning, not a reported customer incident or a claim of testing on your stack.
Consider a database budget of 180 application connections. Six replicas with pools of 30 already use the entire budget; a rollout temporarily adding two replicas permits 240. Even without a leak, deployment can exhaust capacity. Include rollout surge, background jobs and an administrative reserve when choosing each pool limit.
Verify recovery
- Confirm new connections succeed and application pool wait time falls under normal traffic, not only after a service restart.
- Check transaction latency and database memory as traffic returns. Reconcile every replica's pool limit with the shared budget.
Rollback and stopping point
Record old pool settings and scale gradually. If a change increases database contention, restore the last sustainable configuration while retaining traffic limits. Terminated transactions cannot be restored by undoing a configuration change.
Prevention and long-term repair
- Set pool limits below the database connection budget.
- Track pool wait time, acquisition timeouts and connection lifetime.
- Alert on slow queries before the pool becomes a queue.
References and corrections
Use the documentation for your installed version. The references below explain the underlying behavior; commands still need environment-specific validation.
Report a correction to Kevin — include the page URL, version and a redacted reproduction. See our editorial policy.