Every connection costs memory whether it is doing work or waiting. Raising the limit on a server that is already at its memory ceiling turns a database error into a machine that swaps, which is worse.
Look at what is connected
SHOW PROCESSLIST;
SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';
- Many rows in Sleep - connections opened and never closed. An application problem, not a database one.
- Many rows running the SAME query - one slow query, arriving faster than it finishes. Fix the query.
- Long-running Locked rows - one transaction holding a lock while everything queues behind it.
Connections that are never closed
A script that opens a connection per loop iteration, or a persistent connection pool larger than the server allows, will exhaust the limit no matter how high it is set.
SHOW VARIABLES LIKE 'wait_timeout';
-- default is often 28800: eight hours of holding a sleeping connection
Lowering wait_timeout to a few minutes reclaims abandoned connections. It is a safety net for a leak, not a cure.
When raising it IS right
If the connections are all doing real work and the server has memory to spare, the limit is genuinely too low.
SET GLOBAL max_connections = 300;\n-- and in my.cnf so it survives a restart
Work out the memory per connection first. 300 connections at 12MB each is 3.6GB before the database has cached a single row.
A sudden jump in connections at a fixed time is a cron job, not traffic. The processlist during the spike names it in one line.