Sizing Pools Against Core Count
Derive pool and max_connections limits from CPU and workload to avoid thrashing.
Why Pool Size Is Not Connection Count
A common mistake is treating the connection pool as a buffer you can grow freely. With PgBouncer in front of PostgreSQL, you actually run two limits: how many clients can talk to PgBouncer, and how many server connections PgBouncer keeps open to PostgreSQL.
max_client_conncan be large (thousands) — these are cheap proxied sockets.default_pool_size(and PostgreSQLmax_connections) is the expensive number — each one is a real backend process.
This lesson is about choosing that expensive number from your CPU core count and workload, so the database does real work instead of thrashing between too many backends.
One Backend = One Process
Each PostgreSQL connection is backed by a dedicated OS process. When you have more active backends than CPU cores, the kernel time-slices them. Past a point, adding connections does not add throughput — it adds context switches, lock contention, and memory pressure.
You can see how many backends exist right now and how many are actually running queries:
SELECT state, count(*)
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY state
ORDER BY count(*) DESC;All lessons in this course
- Why Connections Are Expensive in PostgreSQL
- Transaction vs Session Pooling Modes
- Sizing Pools Against Core Count
- Diagnosing Pool Saturation and Queueing