MySQL error 1040 means the server has reached its max_connections limit, so every new client is refused until an existing connection closes. Existing sessions keep working, which is why the site may be half-broken: some requests succeed while others fail.
You see it as Too many connections in the MySQL client, as SQLSTATE[08004] [1040] or [HY000] [1040] in PHP, and as database connection errors or HTTP 500 responses on pages that need the database. MySQL deliberately keeps one extra connection available for an administrator, so you can usually still log in as root to investigate.
Causes, most likely first
- Slow queries piling up. Each request holds a connection while its query runs. One slow query under traffic multiplies into hundreds of waiting connections.
- Too many application workers. Hundreds of PHP-FPM children, Node processes or app instances, each with its own connection, exceed the limit.
- Connection leaks. Code that opens connections and never closes them, or long-lived workers with idle connections.
- A traffic or bot spike, such as a crawler or a login attack hitting dynamic pages.
max_connectionsset too low for a legitimate workload. The default is commonly 151 on MySQL, but check your own value.- Locks. A long transaction holding locks makes others wait, keeping their connections open.
Step 1: log in and look
SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW FULL PROCESSLIST;
If you cannot get in, try mysql -u root -p on the server itself using the reserved extra connection. Look at the process list: which user and host own most connections, what state they are in (Sleep, Sending data, Waiting for table metadata lock), and how long they have run (the Time column).
Summarize quickly:
SELECT user, host, COUNT(*) AS n, SUM(command = 'Sleep') AS sleeping
FROM information_schema.processlist
GROUP BY user, host ORDER BY n DESC;
Many Sleep connections with high Time values suggest leaks or oversized worker pools. Many active long-running queries suggest a slow query problem.
Step 2: relieve the pressure now
Kill the worst offenders by ID from the process list:
KILL 12345;
Raise the limit temporarily (no restart, lost on restart):
SET GLOBAL max_connections = 300;
Step 3: make the limit permanent, with care
In /etc/mysql/mysql.conf.d/mysqld.cnf or /etc/my.cnf:
[mysqld]
max_connections = 300
wait_timeout = 120
interactive_timeout = 120
Each connection uses memory for buffers (sort, join, thread stack and others), so raising max_connections blindly can push the server into swap or an out-of-memory kill. A rough sanity check is Max_used_connections times the per-connection buffers plus the global buffers such as innodb_buffer_pool_size; keep that well under total RAM. wait_timeout closes idle connections after that many seconds; the default of 28800 (8 hours) is very generous for web workloads, though lowering it can cause "server has gone away" for pooled long-lived clients, see MySQL server has gone away.
Step 4: fix the demand side
Raising the limit treats the symptom. Reduce what clients ask for:
- Slow queries. Enable the slow log:
SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 1;then inspect the log file and add indexes withEXPLAIN. - Worker counts. Make sure total possible workers (PHP-FPM
pm.max_childrenacross all pools plus cron and queue workers) stay belowmax_connectionswith headroom. - Close connections. Release them in
finallyblocks, avoid persistent connections in PHP (mysqli_pconnect,PDO::ATTR_PERSISTENT) unless you have sized for them, and use a connection pool with a fixed maximum in Node, Java or Python apps. - Cache. Page caching or an object cache (Redis, Memcached) removes many queries entirely.
- Rate-limit abusive traffic at the web server or CDN layer.
- Connection proxies. ProxySQL or MariaDB MaxScale can multiplex many client connections over fewer server connections.
How to verify
Watch Threads_connected fall back to a normal baseline, and compare Max_used_connections against max_connections after traffic returns; a healthy server stays well below the limit. Check the site with the HTTP स्टेटस चेकर and measure response times with the वेबसाइट स्पीड टेस्ट to see whether slow pages have recovered. Keep an अपटाइम मॉनिटर on a database-backed page to catch recurrences.
अगले कदम
- Test a database-backed URL with the वेबसाइट हेल्थ चेक.
- Read reduce time to first byte for slow backend response causes.
- Learn about connection refused errors when the server is not reachable at all.
- Add an अपटाइम मॉनिटर to be alerted on recurrence.
सामान्य प्रश्न
What is a good max_connections value?
It depends on RAM and workload. Start from how many connections you actually use (Max_used_connections), add headroom, and confirm memory can support it. Many small sites run fine with the default.
Why can I still log in as root when others cannot?
MySQL reserves one extra connection for accounts with the CONNECTION_ADMIN or SUPER privilege so an administrator can diagnose. Do not give application users that privilege.
Does restarting MySQL fix it?
It clears the connections briefly, but if the cause is slow queries or leaks the error returns within minutes. Treat a restart as a last resort and find the cause.
Is this the same error as a WordPress database connection error?
WordPress shows "Error establishing a database connection" for many causes, and error 1040 is one of them. Check the MySQL error log or enable WP_DEBUG_LOG to see the real code.
Get notified when this fix updates
Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.
यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.