MySQL max_user_connections Error: Causes and the Fix
Your site throws "Error establishing a database connection," but when you check the MySQL error log or a debug query, the real message is ERROR 1226 (42000): User 'dbuser' has exceeded the 'max_user_connections' resource (current value: 20). If that looks familiar, you're not hitting a server-wide MySQL limit — you're hitting a per-account cap, and the fix is completely different from the usual "raise max_connections" advice.
What max_user_connections actually is
MySQL has two separate connection ceilings, and mixing them up wastes a lot of troubleshooting time:
| Limit | Scope | Who sets it | Typical error |
|---|---|---|---|
max_connections | Whole MySQL server, all users combined | Server admin, in my.cnf | ERROR 1040: Too many connections |
max_user_connections | One specific database user only | Per-account grant, or a WHM/cPanel resource limit | ERROR 1226: User has exceeded the 'max_user_connections' resource |
On shared cPanel hosting, every account usually gets its own database user with its own cap on simultaneous connections — often somewhere between 10 and 25, depending on the plan. The rest of the server can be sitting nearly idle and you'll still get locked out the moment your site alone opens more connections than your account is allowed.
Why it happens
Traffic burst on a low-limit plan
A sale, a newsletter blast, or a bot crawl can spin up more concurrent PHP processes than usual. Each one opens its own MySQL connection, and on a plan capped at 15–20 connections per user, that's not much headroom. Entry-level shared hosting plans are sized for typical traffic, not spikes, precisely because most accounts on the server never come close to their cap — until one day yours does.
Connections that don't close cleanly
Persistent connections (mysqli_connect with the p: prefix, or some poorly written plugins) can hang around longer than they should. So can PHP-FPM workers that stay busy on a slow page and hold their DB connection the whole time. A single slow query — an unindexed WooCommerce lookup, say — can tie up a connection for seconds instead of milliseconds, and if enough requests pile up behind it, you run out of slots even though total traffic looks unremarkable in your analytics.
Multiple sites sharing one database user
If you've pointed two or three WordPress installs at the same MySQL user to save on account limits, their connection counts stack. One site's traffic spike can lock out the others.
A runaway cron job or import script
WP-CLI loops, migration scripts, or a cron job that fires every minute and doesn't release its connection properly will quietly eat your quota in the background, so the error shows up even during low traffic.
Confirm it's really this, not the server-wide limit
Don't guess — check. If you have SSH or Terminal access in cPanel:
mysql -u your_db_user -p -e "SHOW VARIABLES LIKE 'max_user_connections';"
mysql -u your_db_user -p -e "SELECT COUNT(*) FROM information_schema.processlist WHERE user='your_db_user';"
If the second number is sitting right at or above the first, that's your answer. On shared hosting without shell access, check cPanel → MySQL Databases or the resource usage panel — some hosts surface the current connection count there, or you can just check the exact wording of the error your site is throwing. "max_user_connections" in the message means per-user, not server-wide.
How to fix it
On shared cPanel hosting (no root access)
You can't edit my.cnf here — the limit is enforced by the hosting account's resource package. Two real options:
- Ask your host to raise the per-account MySQL connection limit. On Getwebup this is a quick change on our side once we confirm it won't affect neighboring accounts on the same server.
- Reduce how many connections your site opens at once — see the fixes below before assuming you need a bigger limit.
On a VPS or dedicated server with root MySQL access
You can set the per-user limit directly:
ALTER USER 'your_db_user'@'localhost' WITH MAX_USER_CONNECTIONS 50;
FLUSH PRIVILEGES;
On older MySQL/MariaDB versions where ALTER USER ... WITH isn't supported, use:
GRANT USAGE ON your_database.* TO 'your_db_user'@'localhost' WITH MAX_USER_CONNECTIONS 50;
Set it high enough to cover real peak traffic, but remember it's still bounded by the server-wide max_connections — raising one without checking the other just moves the wall.
Fix what's actually eating connections
Raising the cap buys time; it doesn't fix a leak. Check these first:
- PHP-FPM pool size. If
pm.max_childrenin your PHP-FPM pool config is set much higher than your MySQL user's connection limit, every busy moment will hit the wall. Bring them in line. - Persistent connections. If a plugin or custom code uses
mysqli_pconnector PDO persistent mode, connections can sit open between requests. Turning persistent connections off usually clears this up fast. - Object caching. A Redis or Memcached object cache in front of WordPress cuts the number of database round-trips per page load significantly, which lowers concurrent connection pressure during traffic spikes.
- Cron and import scripts. Make sure long-running WP-CLI or migration scripts explicitly close their MySQL connection when done, and don't schedule the same heavy cron job to overlap itself.
Prevention checklist
- Give each site its own database user instead of sharing one across multiple installs.
- Match your PHP-FPM
pm.max_childrento what your MySQL connection limit can actually support. - Add an object cache (Redis or Memcached) if your site does more than a trickle of traffic.
- Monitor connection counts before a planned traffic event — a sale, a launch, a press mention — and ask your host to raise the limit in advance rather than mid-outage.
- Avoid persistent MySQL connections unless you've specifically tuned your stack for them.
If you're on Getwebup hosting and keep hitting this ceiling even after cleaning up connection usage, it's usually a sign your plan's resource limits no longer match your traffic — worth a quick chat with support before it becomes a recurring outage.
Frequently asked questions
What's the difference between max_connections and max_user_connections?
max_connections is a server-wide MySQL setting that caps total connections from every user combined. max_user_connections caps connections from one specific database user, regardless of how busy the rest of the server is. On shared cPanel hosting, you'll usually hit the per-user limit long before the server-wide one.
Can I fix this myself on shared hosting?
You can't edit the limit directly without root access, but you can reduce how many connections your site opens at once by tuning PHP-FPM, disabling persistent connections, and adding an object cache. If that's not enough, ask your host to raise the per-account limit.
Will restarting MySQL fix it?
It clears the immediate backlog by closing all open connections, but it's a temporary fix. If the underlying cause — a leak, an undersized limit, or an overlapping cron job — isn't addressed, the error comes back.
Does WordPress show a specific error for this, or just the generic database message?
WordPress shows the same generic 'Error establishing a database connection' screen regardless of the cause. You have to check the MySQL error log, enable WP_DEBUG, or query the database directly to see the actual max_user_connections message.
How do I know what limit my hosting plan gives me?
Run SHOW VARIABLES LIKE 'max_user_connections'; against your database user if you have any command-line or phpMyAdmin SQL access. If you can't run queries, check your hosting plan's resource limits page or ask support directly.