dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Home/Error Library/postgresql-too-many-connections-for-role
PostgreSQL
PG 14 - 17Connection & Pool
5 min read
FATAL: too many connections for role "app_user"

PostgreSQL Role Connection Limit Exhaustion: Root Cause, Emergency Sizing & Role-Based Pooling

Diagnosing ALTER ROLE CONNECTION LIMIT exhaustion during pod scaling, emergency limit override, and PgBouncer user-level pool isolation.

Reviewed by:Senior Database Architect & SRE (dataiotech Labs)
Tested Versions: PostgreSQL 14 / 15 / 16 / 17

Operational Verification & Reliability Metadata

Last Technical Review: 2 Kasım 2026
Tested VersionsPostgreSQL 14.10, 15.6, 16.4, 17.11 (Ubuntu 24.04)
Required PrivilegesSUPERUSER or CREATEROLE
Risk Assessment
MediumSetting CONNECTION LIMIT to -1 risks exhausting cluster-wide max_connections
Expected OutputActive session count for role dropping below CONNECTION LIMIT in pg_stat_activity
Rollback Procedure:Re-apply explicit budget via ALTER ROLE app_user CONNECTION LIMIT 50;
PostgreSQL Docs: ALTER ROLE Connection Limits
First 60 Seconds Emergency Protocol:

The error string is a symptom, not the root cause. Do not restart the server blindly. Run the diagnostic queries below to pinpoint the actual failure mode.

▸Symptom

A specific role is rejected at connection handshake while other database users function normally:

plaintext
FATAL: too many connections for role "app_user"

▸What You See in Production

Superusers connect fine, but application pods authenticating as app_user fail with pool timeouts.


▸Root Cause Matrix

ProbabilityRoot CauseDescription
%65Pod Autoscaling SpikeRole quota was set too low relative to pod replica scaling.
%25Application Connection LeakIdle connections accumulated until exhausting the role quota.
%10Stale Quota PolicyHardcoded limits unaligned with production traffic.

▸EMERGENCY RUNBOOK (0-5 min)

sql
-- 1. Inspect role quota and active sessions SELECT rolname, rolconnlimit FROM pg_roles WHERE rolname = 'app_user'; SELECT count(*), state FROM pg_stat_activity WHERE usename = 'app_user' GROUP BY state; -- 2. Emergency override: Set unlimited ALTER ROLE app_user CONNECTION LIMIT -1; -- 3. Terminate stale idle sessions SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE usename = 'app_user' AND state = 'idle' AND state_change < now() - interval '5 minutes';

▸PERMANENT BLUEPRINT

  1. 1Two-Tier Connection Pooling: Deploy PgBouncer in transaction mode.
  2. 2Capacity Budgeting: Set role connection limit to 120% of aggregate pod capacity:
sql
ALTER ROLE app_user CONNECTION LIMIT 60;
  1. 1Session Timeouts: Enforce defensive timeouts per role.

▸Verification

sql
SELECT r.rolname, r.rolconnlimit, count(s.pid) AS active_connections FROM pg_roles r LEFT JOIN pg_stat_activity s ON r.rolname = s.usename WHERE r.rolname = 'app_user' GROUP BY r.rolname, r.rolconnlimit;

Other Database Error Triage Playbooks

Other battle-tested diagnostic guides for high-severity database errors.

All Errors (82)