MySQL Error 1040 occurs when the number of concurrent client connections exceeds the server's max_connections limit. This happens due to insufficient connection limits, poor connection management, slow queries, or traffic spikes. Fix by increasing max_connections, implementing connection pooling, adjusting timeout values, and optimizing queries.
MySQL Error 1040 (SQLSTATE 08004) is triggered when a client attempts to establish a new connection to the MySQL server but the current number of active connections has already reached the max_connections limit. The server refuses the connection to protect itself from resource exhaustion. The MySQL server pre-allocates memory (1-10 MB per connection depending on buffer settings) for each active connection. When the max_connections threshold is breached, no new connections are accepted until existing connections close. This error is a safety mechanism—allowing unlimited connections would eventually exhaust server memory and crash the database. Unlike transient network errors, Error 1040 indicates a capacity problem that requires either increasing server resources, optimizing connection usage, or implementing connection pooling. The error manifests immediately on connection attempts and cannot be retried successfully until underlying conditions improve.
First, determine how many connections are currently active and what the limit is.
-- Show current connection limit
SHOW VARIABLES LIKE 'max_connections';
-- Show maximum connections used since server startup
SHOW STATUS LIKE 'Max_used_connections';
-- Show current active connections
SHOW PROCESSLIST;
-- Get a count of connections by state
SHOW PROCESSLIST;
SELECT state, COUNT(*) FROM information_schema.processlist GROUP BY state;If Max_used_connections is close to max_connections, you are running near capacity. If you see many "Sleep" connections, check the wait_timeout setting.
For immediate relief, increase the limit at runtime (changes persist until next restart).
-- Check current limit
SHOW VARIABLES LIKE 'max_connections';
-- Increase temporarily (no restart required)
SET GLOBAL max_connections = 500;
-- Verify the change
SHOW VARIABLES LIKE 'max_connections';This allows new connections immediately. However, verify that your server has enough memory. As a rough estimate, each connection uses 1-10 MB. For 500 connections, budget 5-50 GB of RAM.
Locate and edit the MySQL configuration file to persist the change across restarts.
# On Linux/Unix, find the config file:
# /etc/mysql/mysql.conf.d/mysqld.cnf (Debian/Ubuntu)
# /etc/my.cnf (CentOS/RHEL, generic)
# /usr/local/mysql/etc/my.cnf (macOS with Homebrew)
# Edit the config file:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# Find the [mysqld] section and add or modify:
[mysqld]
max_connections = 500
# Save and exit (Ctrl+X, Y, Enter in nano)
# Restart MySQL to apply:
sudo systemctl restart mysql
# or on macOS:
brew services restart mysql
# Verify the change persisted:
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"Choose a value appropriate for your workload. Start with 500-1000 for typical applications, or 2000+ for high-concurrency systems.
Idle connections waste capacity. Reduce wait_timeout and interactive_timeout to close connections that are no longer in use.
-- Check current timeouts (default is 28800 seconds = 8 hours)
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';
-- Set shorter timeouts at runtime (300 seconds = 5 minutes)
SET GLOBAL wait_timeout = 300;
SET GLOBAL interactive_timeout = 300;
-- Verify:
SHOW VARIABLES LIKE '%timeout%';Make the change permanent in your config file:
[mysqld]
wait_timeout = 300
interactive_timeout = 300Then restart MySQL. This aggressively closes idle connections, freeing capacity for new ones.
Connection pooling reuses connections instead of creating new ones, dramatically reducing the connection count.
For Node.js (MySQL2):
const pool = mysql.createPool({
connectionLimit: 10,
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb'
});For Python (SQLAlchemy):
engine = create_engine(
'mysql+pymysql://root:password@localhost/mydb',
pool_size=10,
max_overflow=20,
pool_pre_ping=True
)For Java (HikariCP):
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
DataSource ds = new HikariDataSource(config);Start with a pool size of 10-20 and monitor connection usage. Always close connections explicitly after queries complete.
Long-running queries hold connections open, reducing available slots. Enable and monitor the slow query log.
-- Enable slow query logging at runtime
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- Log queries taking >2 seconds
SET GLOBAL log_queries_not_using_indexes = 'ON';
-- Make permanent in config file:
[mysqld]
slow_query_log = 1
long_query_time = 2
log_queries_not_using_indexes = 1
slower_log_file = /var/log/mysql/slow.logAfter running for a few hours, analyze the slow query log:
# Install mysqldumpslow if needed
sudo apt-get install mysql-server
# Analyze slow queries
mysqldumpslow /var/log/mysql/slow.log | head -20Add indexes to frequently run slow queries, or refactor queries to use existing indexes.
As an emergency measure, terminate sleeping or long-running connections to free capacity.
-- Show all connections
SHOW PROCESSLIST;
-- Kill a specific connection by ID
KILL CONNECTION 12345;
-- Kill all connections except the one executing this command
SELECT GROUP_CONCAT(CONCAT("KILL ", id)) FROM information_schema.processlist WHERE id != CONNECTION_ID() AND command != "Sleep";
-- Run the output of the above, or use a script:
KILL 101;
KILL 102;
KILL 103;Warning: Only use this for troubleshooting. Killing connections can disrupt transactions. A better long-term fix is connection pooling.
In MySQL 8.0.14+, enable the admin connection feature which reserves one extra connection for users with CONNECTION_ADMIN privilege. This allows DBAs to connect and investigate even when all regular connections are exhausted: SET GLOBAL admin_address = '127.0.0.1'; SET GLOBAL admin_port = 33062;
For connection pool exhaustion in application frameworks, ensure connections are returned to the pool after use. Common mistakes include not closing result sets, exceptions breaking the return path, or queries that wait for locks. Use tools like pgBouncer or ProxySQL as a middleware multiplexer to convert many application connections into fewer database connections.
On shared hosting or cloud databases, check platform-imposed limits. AWS RDS has limits based on instance size, and some managed services cap connections lower than the server's configured max_connections.
Monitor connections using this query for long-term capacity planning:
SELECT COUNT(*) as active_connections FROM information_schema.processlist WHERE command != 'Sleep';If you consistently approach 80% of max_connections, increase the limit further or investigate architectural changes (read replicas, connection pooling, microservices).
EE_WRITE (3): Error writing file
How to fix "EE_WRITE (3): Error writing file" in MySQL
CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters
How to fix "CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters" in MySQL
CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed
How to fix "CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed" in MySQL
ERROR 1146: Table 'database.table' doesn't exist
How to fix "ERROR 1146: Table doesn't exist" in MySQL
EE_READ (2): Error reading file
How to fix "EE_READ (2): Error reading file" in MySQL