sfw/fix
HY000/1040 critical

MySQL Error 1040: Too many connections

Open client connections reached max_connections, so MySQL refused every new connection until existing ones closed.

What you see

ERROR 1040 (HY000): Too many connections
SQLSTATE[HY000] [1040] Too many connections

What’s actually happening

Pages that hit the database suddenly fail while MySQL itself is still running. App logs and the mysql CLI both return "ERROR 1040 (HY000): Too many connections." It tends to strike during a traffic spike or after a connection leak builds up over hours. New logins are rejected, but queries already holding a connection keep working, so the failure looks partial and confusing.

Common causes

  • Concurrent connections exceeded max_connections (default 151 on a stock MySQL/MariaDB install).
  • An application or framework opening connections without closing them — a leak that climbs until it hits the cap.
  • A connection pool (PHP-FPM children × pool size, or app server replicas) configured to allow more total connections than MySQL accepts.
  • Long-running or stuck queries holding connections open far longer than expected, often from missing indexes or lock waits.
  • A traffic surge or retry storm where clients pile up faster than queries complete.

How to fix it

  1. See who's connected right nowFrom the CLI: `SHOW PROCESSLIST;` (or SELECT * FROM information_schema.processlist) shows every connection, its state, and how long it's been idle. `SHOW STATUS LIKE 'Threads_connected';` and `Max_used_connections` tell you how close you've been running to the limit. If you can't even log in, MySQL reserves one slot for SUPER — connect as root.
  2. Raise max_connections (with headroom in mind)Live bump: `SET GLOBAL max_connections = 500;`. Make it permanent in my.cnf under [mysqld]: `max_connections = 500`. Each connection costs RAM, so don't just crank it — confirm the box has memory for buffers × connections before setting it high.
  3. Kill stuck connections to recover fastIf a few sleeping or long-running threads are eating the pool, `KILL <id>;` the worst offenders from SHOW PROCESSLIST. This buys breathing room while you fix the root cause; it isn't a permanent fix.
  4. Fix the leak at the app layerMake sure connections are returned/closed — in PHP, persistent connections (PDO::ATTR_PERSISTENT) plus many FPM workers multiply fast. Cap pool size so (app instances × pool max) stays comfortably under max_connections, and set a sane wait_timeout so idle connections get reaped.
  5. Tackle the slow queries holding connectionsEnable the slow query log, then EXPLAIN the worst offenders and add the missing indexes. A query that should take 5ms but takes 5s ties up its connection 1000x longer, and a handful of those under load is enough to exhaust the cap.

Stop it recurring

Monitor Threads_connected against max_connections and alert at ~80% so you catch a climbing leak before it locks out the whole app.

Related errors