PostgreSQL refuse les connexions « too many clients already »
```text FATAL: sorry, too many clients already FATAL: remaining connection slots are reserved for non-replication superuser connections ```
Détecter
L'application renvoie des erreurs 500 en rafale ; les nouveaux pods ou workers n'arrivent pas à se connecter à la base. Le problème apparaît après une montée en charge ou un scale-out.
Symptômes
L'application renvoie des erreurs 500 en rafale ; les nouveaux pods ou workers n'arrivent pas à se connecter à la base. Le problème apparaît après une montée en charge ou un scale-out.
Environnement
PostgreSQL 16 (max_connections = 200), application déployée sur 12 instances ayant chacune un pool de 20 connexions.
Cause racine
12 × 20 = 240 connexions potentielles > 200 autorisées. De plus, de nombreuses sessions sont idle in transaction, bloquant des slots (et des verrous) inutilement.
Diagnostic
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
SELECT usename, application_name, client_addr, state, now() - state_change AS depuis
FROM pg_stat_activity WHERE state = 'idle in transaction' ORDER BY depuis DESC;
Solution
- Court terme : terminer les sessions
idle in transactionanciennes (pg_terminate_backend) et réduire la taille des pools applicatifs. - Durable : placer PgBouncer en mode
transactiondevant la base ; dimensionnerpool_size × instancessousmax_connections. - Fixer
idle_in_transaction_session_timeout = '60s'.
Commandes
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE state = 'idle in transaction' AND now() - state_change > interval '5 minutes';
ALTER SYSTEM SET idle_in_transaction_session_timeout = '60s';
SELECT pg_reload_conf();
Prévention
Budget de connexions documenté par application, pooler systématique, alerte à 80 % de max_connections, test de charge incluant le scale-out.