Your site is normally fast, but during traffic spikes visitors get a database error instead of pages, and the log shows Too many connections. MySQL is refusing new connections because every slot is taken. Here is where the error comes from, how to diagnose it and how to keep the site stable under load.
How error 1040 works
The max_connections setting caps how many connections can be open at the same time on the whole server. Each PHP process connects to the database to build a page and holds the connection until it finishes. When the cap is reached, new attempts fail:
ERROR 1040 (HY000): Too many connections
This is a server-wide error. A per-user cap produces 1203 max_user_connections instead, and an exhausted hourly quota produces 1226, so check the exact code first.
Why connections run out
The usual cause is not raw visitor numbers but connections staying busy too long. If a page takes 50 ms, a hundred connections can serve a lot of traffic. But one slow query that locks a table makes other queries wait, each holding its own connection, and within seconds the pool is full. Bots crawling filter pages, uncached heavy pages, long export scripts, and more PHP workers than the database can handle all make it worse.
Diagnostic commands
With your own VPS or admin access, compare the limit with current and peak usage. If Max_used_connections equals the limit, the server really hit the ceiling:
SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
Then see what the connections are doing. Many rows with a large Time or the state Waiting for table metadata lock point to a specific query rather than load:
SHOW FULL PROCESSLIST;
-- stop a hopelessly stuck query:
KILL 48213;
MySQL keeps one extra connection beyond the limit for a privileged administrator, so root can usually still log in.
Raising the limit and closing idle connections
# temporary, until restart
SET GLOBAL max_connections = 300;
# permanent: /etc/mysql/my.cnf or /etc/my.cnf, [mysqld] section
[mysqld]
max_connections = 300
wait_timeout = 120
# then restart (service name depends on the system)
sudo systemctl restart mysql
A lower wait_timeout stops idle connections from occupying slots for hours. Do not raise the limit blindly: every connection uses memory for its buffers, and a small server allowing a thousand connections can run out of RAM at peak. Size it together with available memory and innodb_buffer_pool_size. On shared hosting these settings are managed by the provider.
What to do in the application
- Enable page caching so cached pages never touch the database.
- Use the slow query log and add indexes to the heaviest queries so connections free up faster.
- Restrict unnecessary bots, especially those crawling filter and search pages.
- Move heavy exports and reports to quiet night hours.
- Match the number of PHP workers to the database connection limit.
Example: exam results day
A private school in Tashkent, misol.uz, ran smoothly all year until entrance exam results were published and thousands of parents opened the results page at once. Within minutes it returned Too many connections. Each page view scanned the whole table on an unindexed column, taking several seconds. After adding an index the query took milliseconds, the page got a short cache, and the error never returned without touching the connection limit. If your site is on sayt.uz hosting and the error keeps recurring, open a support ticket with the time and page address.
Prepare ahead
Connections usually run out during predictable events such as sales, result announcements and ad campaigns. Load-test the busiest pages beforehand, confirm caching works and fix slow queries so the site holds up exactly when it matters most.