Come appare il messaggio
FATAL: sorry, too many clients already
connection to server at "db" (10.0.0.5), port 5432 failedCause frequenti
- L'applicazione apre connessioni e non le chiude, per esempio dopo un deploy o in un worker senza
finally. - La somma di tutti i pool supera
max_connections, soprattutto con più istanze o container. - Un PgBouncer in modalità
sessioninoltra ogni connessione del client e annulla il pooling. - Le transazioni restano
idle in transactione tengono gli slot senza lavorare. - Backup, monitoraggio e job di migrazione si aggiungono ai pool dell'applicazione.
Verifica
- Connessioni usate e consentite
psql -c "SELECT count(*) AS used, current_setting('max_connections')::int AS max FROM pg_stat_activity;" - Chi tiene le connessioni?
psql -c "SELECT usename, state, count(*) FROM pg_stat_activity GROUP BY 1,2 ORDER BY 3 DESC;" - Transazioni idle lunghe
psql -c "SELECT pid, now()-state_change AS idle_for, query FROM pg_stat_activity WHERE state LIKE 'idle in transaction%' ORDER BY 2 DESC LIMIT 10;" - Slot riservati
psql -c "SHOW superuser_reserved_connections;"
Soluzione
- Prima misura, poi aumenta: alzare
max_connectionsnasconde solo il leak e costa memoria per ogni backend. - Chiudi il leak: usa context manager o
finallye tieni ogni pool sottomax_connections / istanze. - Con molte connessioni brevi metti PgBouncer in modalità
transactiondavanti al database. - Imposta
idle_in_transaction_session_timeoutper terminare le transazioni bloccate. - Aumenta il limite solo con margine di memoria per autovacuum e backup, ricordando che richiede un riavvio.
Domande frequenti
Basta alzare max_connections?
Per poco. Con un leak l'errore torna in poche ore. Prima misura chi occupa gli slot.
Perché ci sono meno connessioni libere di quanto dica max_connections?
Gli slot riservati a superuser e processi di background contano nel limite, quindi un client normale lo raggiunge prima.