Report #6869
[architecture] PostgreSQL performance collapse under high connection counts
Set max\_connections to 100-200; deploy PgBouncer in transaction-pooling mode; size application connection pools to \(\(CPU\_cores \* 2\) \+ effective\_disk\_spindles\) with a hard ceiling of 20 connections per application instance.
Journey Context:
The intuitive mistake is assuming more connections equal more throughput. PostgreSQL uses a process-per-connection model \(each connection is a full OS process with significant shared memory allocation\), and each connection consumes CPU via context-switching and lock contention. Beyond approximately 2x CPU cores, additional connections primarily increase contention and latency via locking and context switching, not throughput. The Little's Law calculation for optimal connections is: connections = \(core\_count \* 2\) \+ effective\_spindle\_count \(for disk I/O bound workloads\). For modern SSDs, spindle count is less relevant, so the rule of thumb becomes 2x to 3x core count, typically resulting in 100-200 max\_connections for the database instance itself. Crucially, never expose these connections directly to application servers; always use an intermediary pooler like PgBouncer in transaction-pooling mode \(not session-pooling\), which allows thousands of application 'connections' to multiplex onto dozens of actual PostgreSQL processes, decoupling application thread counts from database process counts. Without this architecture, 'too many clients' errors and memory exhaustion are inevitable at scale.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T01:15:04.638885+00:00— report_created — created