Erreur PostgreSQL : sorry, too many clients already

FATAL:  sorry, too many clients already

Chaque slot de connexion du serveur est occupé, donc PostgreSQL refuse le nouveau. Le serveur est par ailleurs en bonne santé — il est simplement plein. Une variante proche du même problème est le message concernant « remaining connection slots are reserved » : les derniers slots sont réservés aux superutilisateurs afin qu'un administrateur puisse toujours entrer et corriger les choses.

Ce que signifie cette erreur

PostgreSQL accepte au plus max_connections connexions concurrentes (par défaut : 100), et en réserve une poignée (superuser_reserved_connections, par défaut : 3) pour les superutilisateurs. Lorsqu'un client ordinaire demande une connexion au-delà de la limite non réservée, il obtient ce FATAL au moment de la connexion — la connexion est refusée, rien d'autre sur le serveur n'est affecté.

Chaque connexion est un processus serveur dédié avec sa propre mémoire, donc la limite existe pour une raison : PostgreSQL ne gère pas des milliers de connexions directes avec grâce. C'est pourquoi la solution durable n'est presque jamais « augmenter le nombre ».

Causes fréquentes

Comment la diagnostiquer

Connectez-vous en tant que superutilisateur (c'est à cela que servent les slots réservés) et regardez qui détient les slots :

SHOW max_connections;

SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state ORDER BY count(*) DESC;

SELECT usename, application_name, count(*)
FROM pg_stat_activity
GROUP BY 1, 2 ORDER BY count(*) DESC;

-- Sessions en transaction depuis le plus longtemps (candidates aux fuites) :
SELECT pid, usename, state, now() - xact_start AS xact_age, left(query, 60)
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_start
LIMIT 10;

Beaucoup de connexions idle pointent vers des pools applicatifs surdimensionnés ou qui fuient ; d'anciennes sessions idle in transaction pointent vers du code applicatif qui a ouvert une transaction et est parti ailleurs.

Comment la corriger

🔍 À lire aussi : VACUUM & bloat — ces sessions idle in transaction ne font pas que dévorer des slots : elles retiennent le vacuum pour toute la base de données.