Guides

"Too many connections" in MySQL and MariaDB: why it happens and what to change

A practical guide to the "Too many connections" error: a quick check, causes ranked by frequency, how to calculate max_connections based on RAM, pooling and object caching.

UptimeMag editorial team · 8 October 2026 · 4 min read

«Too many connections» su MySQL e MariaDB: perché capita e cosa cambiare

Quick check (30 seconds)

First of all, you need to establish whether the limit is actually full right now. From the command line, on any system running MySQL or MariaDB:

mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections'; SHOW STATUS LIKE 'Threads_connected';"

If Threads_connected is close to or equal to the max_connections value, the limit is saturated right now. If it's much lower, the error you saw in the log was a spike that has already passed, and the problem is intermittent: the causes to look at are different, see below.

To see who's holding connections open:

mysql -u root -p -e "SHOW FULL PROCESSLIST;"

The column that matters is Command: if you see lots of rows with Sleep and a high Time, connections aren't being closed by the application — it's not a genuine traffic spike.

What the error means

MySQL and MariaDB accept a maximum number of simultaneous connections, set by the max_connections parameter. When this number is reached, the server rejects new connections with the error ERROR 1040 (HY000): Too many connections, even if the database still has spare CPU and disk capacity. The site isn't slow: it's the database shutting the door on new arrivals.

The causes, ranked by frequency

1. Persistent or sleeping connections left open

This is the most common cause on sites with a control panel or CMS that opens a connection per page and doesn't close it promptly. You can confirm this with SHOW FULL PROCESSLIST as above: many Sleep rows with a Time above 60-100 seconds indicate an application that isn't releasing connections, or a poorly configured pool on the PHP-FPM side (persistent connections with mysqli_connect in p: mode).

Solution: disable persistent connections at the application level if they aren't managed by a dedicated pool, and set a lower wait_timeout to close idle sleeping connections. On Ubuntu 24.04 with Nginx and PHP-FPM, this is edited in /etc/mysql/mysql.conf.d/mysqld.cnf (path documented by MariaDB, see below) by adding wait_timeout = 60 under [mysqld], then restarting with sudo systemctl restart mariadb (or mysql, depending on the installed package). On cPanel, the equivalent file is /etc/my.cnf, which can be edited via WHM > MySQL/MariaDB Configuration or by hand, then service mysql restart. On Plesk, the path is the same /etc/my.cnf or /etc/mysql/my.cnf depending on the distribution, also manageable from Tools & Settings > MySQL Settings.

2. max_connections raised without considering memory

Here the risk runs the other way: bumping the number up at random to "make the error go away", without calculating how much RAM is required, causes the server to run out of memory (OOM), with the MySQL process killed by the kernel — a worse outcome than a plain 1040 error.

You can check this by looking at how much memory is allocated per thread. MariaDB's official documentation (mariadb.com/kb/en/mysqld-options/#-max-connections) states that each connection consumes memory for the thread stack, sort buffers, join buffers and read buffers, on top of the shared buffer pool. A cautious estimate: RAM available to MySQL divided by roughly 12-15 MB per connection (an indicative figure that varies with the configured sort_buffer_size, join_buffer_size and thread_stack), net of the RAM reserved for innodb_buffer_pool_size and the operating system.

Example: on a server with 4 GB of RAM dedicated solely to MySQL, if 2.5 GB is allocated to innodb_buffer_pool_size, 1.5 GB remains for connections: at 12 MB per connection, that's around 125 connections — not the 500 you often see set at random in generic guides.

Solution: calculate the value using the formula above, rather than copying it from another guide. It's set in the same mysqld.cnf file with max_connections = <calculated value>, followed by a service restart.

3. No connection pool or object cache

If the application (CMS, hosting panel, e-commerce platform) opens a new connection for every request instead of reusing them, the number of simultaneous connections grows linearly with traffic, and any value of max_connections will eventually saturate during peaks.

You can check this by seeing whether Threads_connected tracks the pattern of visits (peaks coinciding with traffic) and whether the CMS's object cache (e.g. Redis or Memcached for WordPress/WooCommerce) is inactive: without a cache, every page re-runs queries against the database instead of reading from the cache.

Structural solution: a connection pool such as ProxySQL sitting in front of the database reduces the actual connections made to MySQL/MariaDB by keeping them open and reusing them, regardless of how many the application opens. Alternatively, or in addition, an object cache (Redis or Memcached) cuts the number of queries — and therefore the connections required — because pages already served no longer hit the database.

How to verify it's fixed

After making the changes, repeat the initial check under normal load:

mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Max_used_connections';"

Max_used_connections shows the highest peak recorded since the last restart: if it stays reliably below the max_connections value even during the busiest traffic, the problem is resolved. If it starts climbing again, the pool or cache isn't intercepting traffic as expected, and the application-side configuration needs revisiting.

If the problem lies with the provider

On shared hosting or managed VPS, max_connections is often set by the provider and can't be changed by the customer. If the error occurs regularly during traffic peaks, open a support ticket including: the exact time of the error, the output of SHOW FULL PROCESSLIST if accessible, and the site's average traffic during that time window. It's up to the provider to check whether the plan you've purchased includes a connection limit suited to the stated traffic.

Written with the help of artificial intelligence and checked by the editors (EU AI Act, art. 50).