ERROR 1040: Too many connections

Too Many Connections? Stop DB Leaks Now

Database connection leaks crash apps. Here are the real reasons your MySQL or Postgres runs out of connections. Fixes for lazy code, bad pooling, and connection timeouts.

Cause #1: Code That Doesn't Close Connections

This is the number one reason. I've seen it in PHP, Node.js, Python — doesn't matter the language. Someone writes code that opens a connection to the database but never closes it. Every time that code runs, a new connection stays open. After a few hundred requests, your database hits max_connections and dies.

Last month I had a client running a small e-commerce site on a shared server. Every time a customer added an item to cart, their PHP script opened a MySQL connection but forgot to close it. Within 15 minutes of a sale, the whole site went down. Fix was simple — close the connection after the query.

The Fix

For PHP with PDO:

$pdo = new PDO('mysql:host=localhost;dbname=shop', 'user', 'pass');
$stmt = $pdo->query('SELECT * FROM products');
$results = $stmt->fetchAll();
$pdo = null; // close it manually

For Node.js with mysql2:

const conn = await mysql.createConnection({...});
const [rows] = await conn.query('SELECT * FROM products');
await conn.end();

If you're using an ORM like Sequelize or Doctrine, make sure you're not opening connections outside the pool. ORMs often cache connections, but if you call new Sequelize() inside a loop without closing, you'll leak.

Also check your error handlers. If a query throws an exception and you don't close the connection in a finally block, that connection stays open. Use try/catch/finally every time.

Cause #2: Connection Pool Set Too Big

This one gets people who think "more connections = faster" — nope. A pool of 50 connections might look good, but if your database only allows 100 total connections and you have 3 app servers each with a pool of 50, you're already at 150. Add a few leaked connections, and boom — too many connections error.

I fixed a setup at a logistics company last year. They had a Java app with a HikariCP pool set to 100. Their MySQL max_connections was 150. Two instances of the app ran on different servers. That's 200 connections when the DB could only handle 150. The result? Random crashes every few hours.

The Fix

Set your pool size based on your database's max_connections and the number of app instances. A good rule of thumb: take max_connections, subtract 10 for admin tasks, then divide by the number of app servers. So if max_connections is 150 and you have 3 servers, each pool should be no more than (150 - 10) / 3 = ~46 connections per server.

For MySQL check current limit:

SHOW VARIABLES LIKE 'max_connections';

Increase it if needed (but don't go crazy — each connection uses RAM):

SET GLOBAL max_connections = 200;

Also set connection timeout in your pool config. In HikariCP:

HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(20);
config.setConnectionTimeout(30000); // 30 seconds
config.setIdleTimeout(600000); // 10 minutes idle

For pgBouncer or PgPool, same logic applies — keep pool sizes small and match them to your workload.

Cause #3: Connections Not Timing Out

Even if you close connections in code, sometimes a connection hangs because of a slow query, network issue, or a transaction that never commits. If your database doesn't kill these idle connections, they pile up over hours or days.

Had a client whose CRM ran fine for 3 days, then on Thursday afternoons it always crashed. Turned out a reporting script ran a 5-minute query every hour. Each query left a connection in 'sleep' state because the script exited without closing. After 72 hours, they had 72 sleeping connections eating up the pool.

The Fix

Set a wait_timeout on the database server. For MySQL:

SET GLOBAL wait_timeout = 300; // 5 minutes
SET GLOBAL interactive_timeout = 300;

Make these permanent in my.cnf:

[mysqld]
wait_timeout = 300
interactive_timeout = 300
max_connections = 150

For Postgres, set in postgresql.conf:

idle_in_transaction_session_timeout = '5min'
statement_timeout = '30s'

Also monitor active connections to see who's hanging. Check MySQL with:

SHOW FULL PROCESSLIST;

Look for connections that have been in 'Sleep' state for more than a few seconds. Kill them manually if needed:

KILL CONNECTION 12345;

But better to automate with a cron job that runs every 5 minutes and kills connections older than a threshold. Here's a quick bash script for MySQL:

#!/bin/bash
mysql -e "SELECT CONCAT('KILL ', id, ';') FROM information_schema.processlist WHERE command = 'Sleep' AND time > 300" | tail -n +2 | mysql

Quick-Reference Summary Table

Cause Symptom Fix
Code doesn't close connections Connections pile up fast during traffic Close connections after queries, use try/finally
Pool size too big Multiple app servers each grab too many Set pool to (max_connections - 10) / app servers
No timeout on idle connections Sleeping connections accumulate over hours Set wait_timeout / idle_in_transaction_session_timeout

Bottom line: connection leaks happen because someone forgot to close a connection or didn't set limits. Check your code first, then your pool settings, then your database timeouts. That order fixes 95% of cases.

Related Errors in Database Errors
ERROR 1146 (42S02): Table 'db.table' doesn't exist Fix MySQL 'Table doesn't exist' Error for Good MSSQL_RESTORE_3241 SQL Server Backup Restore Fails: Real Fixes That Work Fix phpMyAdmin Configuration File Writable Warning 9002, 824, 823 SQL Server transaction log corrupted — fix it in 3 steps

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.