How to Fix MySQL Too Many Connections Error on cPanel
In this article9 sections
The site suddenly shows “Error establishing a database connection”, or a blank page, and the error log says Too many connections. MySQL and MariaDB limit how many clients can connect at once. When a busy site, a slow query or a stuck script holds connections open, the next request is refused. On a shared cPanel account, the limit is set by the server, so the fix is usually to find what holds the connections, not to ask for a higher number. This guide shows how to see the connections, find the cause, and stop it returning.
On SiteHarbour’s cPanel hosting, the database server is shared by many accounts, so the connection limit exists to protect everyone. The steps below show how to keep your site within it.
Step 1: Confirm the error
Open the error log for the account in cPanel, under Metrics > Errors, or read the PHP log for the domain. Look for Too many connections or max_user_connections. The two messages mean different things. Too many connections means the server as a whole is full. max_user_connections means your account has used its own share. The steps below cover both.
Step 2: See the connections over SSH
Connect over SSH as your cPanel user and list the open connections to the database. This command shows the user, the database, the time each connection has been idle and the query it is running:
mysql -u cpuser_dbuser -p -e "SHOW FULL PROCESSLIST;"
Expected: a table with one row per connection. Look for many rows with the same database, a long Time value, or a Command of Sleep that never clears. Idle connections that stay open are the usual cause on a site that uses a plugin which opens a connection and never closes it. A query with a large Time value is a slow query that holds the others.
Step 3: Count the connections by source
To see which part of the site is responsible, count the connections by their state and their host:
mysql -u cpuser_dbuser -p -e "SELECT COMMAND, COUNT(*) FROM information_schema.PROCESSLIST GROUP BY COMMAND;"
Expected: a count for each command type. A large number of Sleep rows points to idle connections. A large number of Query rows points to slow queries, and the processlist in Step 2 shows which ones.
Step 4: Find the slow query
A query that runs for many seconds holds a connection the whole time. In the processlist, note the Info column for the longest Time value. Common causes on WordPress are a plugin that searches the whole table without an index, a report that reads every order, and a cron job that runs every minute and overlaps with itself. The job that overlaps is covered in how to set up cron jobs in cPanel, which shows how to stop a second run starting while the first is still going.
Stop a single stuck query only if you know it is safe, using its ID from the processlist:
mysql -u cpuser_dbuser -p -e "KILL 12345;"
Expected: the connection closes at once. Replace 12345 with the ID in the first column. Killing a write query in the middle can leave data half changed, so check what it does first.
Step 5: Close the connections your code leaves open
A PHP script that opens a connection and then exits normally closes it. A long-running script, or a loop that opens a new connection on every iteration, does not. For a WordPress site, check for a plugin that runs a long import or a sync on every page load, and turn off the part that runs on every request. For a custom application, reuse one connection per request, and close it when the request ends.
Step 6: Keep your account within its share
If the error reads max_user_connections, the account is over its own share, and the cause is usually traffic or a slow query, not a single bad connection. Lower the demand before you ask for more. Cache the pages that hit the database most, as described in how to speed up WordPress on shared hosting, and clean up the tables that grow without limit. A database that stores logs forever is a common source of slow queries.
cPanel’s Resource Usage page shows the account’s limits. If the same error returns each week at the same hour, the traffic has outgrown the plan, and the move options are in when to move WordPress from shared hosting to a VPS.
Step 7: Confirm the fix
Run the processlist again at the busiest hour. Expected: a count of connections that stays well below the limit, and no long Time values. Check the error log the next day. A clean night is a better test than a single check.
Common mistakes
- Restarting MySQL in the hope it clears. On shared hosting you cannot, and it only hides the cause.
- Killing queries blindly. A killed write can leave data half changed.
- Raising a limit in the code. The limit belongs to the server. Reduce the demand instead.
- Running a long job every minute. It overlaps with itself, and each copy holds connections.
- Ignoring the log table. A table that grows without limit makes every query slower, and slow queries hold connections.
Frequently asked questions
Is “Too many connections” a server fault?
Sometimes, when many accounts are busy at once. Most often it is the site’s own idle or slow connections. Check the processlist before you assume the server is at fault.
Why does the error come back at the same time each day?
A scheduled job or a traffic peak. Find the job in cron, or the page with the most visits in the logs.
Will a database cache solve this?
A page cache reduces the number of database requests, which helps most. An object cache helps on sites that repeat the same queries.
Can I see the limit for my account?
Your plan’s limits are in the account overview. The exact connection limit depends on the server, so check the error message to see which limit you have reached.
“Too many connections” means the database has no free connections for the next request. Look at the processlist, find the idle or slow connections, and fix the code or the job that holds them open. Keep the page cache working, and keep the tables that grow without limit trimmed. For the wider resource picture on a shared account, read how to fix the 508 Resource Limit Is Reached error on cPanel.