Troubleshooting guide · website-errors · Published 2026-08-16 · 3 min read
MySQL too many connections error
MySQL too many connections explained: the connection limit, persistent and leaked connections, and the fixes that keep apps within it.
- ·The too many connections error
- ·Why the pool fills up
- ·Reducing connections
The error and what it means
When an application asks MySQL for a connection and every slot is in use, MySQL refuses with:
ERROR 1040 (HY000): Too many connections
The server has a hard limit, max_connections, that caps how many client connections it accepts at once. Once that number is reached, further attempts fail immediately with the error above. It is not a query failing; it is a connection admission being refused.
To see the current limit and how many are in use:
SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
A typical value is 151, and a small app that opens one connection per request rarely gets close. When the pool fills up, it is usually because a request that should have released a connection did not.
Why the pool fills up
- Persistent connections that never close. PHP's persistent connections stay open after a request. Run under a single-threaded worker mode, they can be reused, but a misconfigured pool or
processors countmismatch keeps far more alive than the app needs. - Connection leaks. Code that opens a connection but skips the close on an error path slowly eats the pool.
- A slow query tying up connections. Queries that run for seconds hold their connection, so a few slow ones can exhaust the limit.
- A connection-per-request pattern without pooling. An application layer that opens a new connection for every operation multiplies the demand.
- Too small a
max_connectionsfor the host. Low-end shared hosts set a low cap and large apps hit it during a traffic spike.
How to fix it
- Find who holds the connections. List clients and their states so you can tell it is the app rather than the server:
SELECT id, user, host, db, command, time FROM information_schema.processlist ORDER BY time DESC;
Look at Command and Time: long Sleep entries are idle, held connections.
- Close connections in code. Every error path must release the connection. A
try / finally(or the language equivalent) that closes in all cases closes the leak. - Cap pooling. If the app uses a connection pool, set a maximum smaller than
max_connections, leaving room for admin sessions and monitoring. Do not point the pool ceiling at the server max. - Chase slow queries. The top
Timerows are the connections to reduce first since holding one costs a whole slot. Add an index or cache and the pool pressure drops with them. - Raise the server limit only as a gate. Raising
max_connectionswithout fixing leaks delays the crash and can exhaust RAM, since every connection costs memory. Prefer reducing demand; reserve a raised limit for a host where the app is within budget.
| Change | Effect on the pool |
|---|---|
| Close connections on every path | Stops the leak at the source |
| Cap app pool below server max | Keeps headroom |
| Fix slow queries | Frees slots quickly |
| Raise max_connections | Adds headroom but costs memory |
A preventive setting
Set the PHP connection handling to release correctly per request and keep the application pool well under the server cap. The database connection error guide covers the "error establishing a database connection" variant that shares the same underlying pool pressure, and a related state is the MySQL server has gone away message that appears when a held connection is killed. Correlating the error log with the process list tells you whether the limit or a leak is the real cause.