Notes on PostgreSQL connection pooling
September 2026
Every PostgreSQL connection is a separate backend process. That is fine for a handful of clients and painful for a few hundred. A pooler in front of the database lets many application connections share a small number of server connections.
Session vs transaction pooling
In session mode a client keeps its server connection until it disconnects, so you gain little. Transaction mode returns the server connection after each transaction, which is where the real savings are, at the cost of session features such as SET and advisory locks.
Sizing
A useful starting point is a pool of roughly two to four connections per CPU core on the database server, then measure. More connections rarely means more throughput; it usually means more lock contention.
[pgbouncer]
pool_mode = transaction
default_pool_size = 20
max_client_conn = 500
Measure wait time in the pooler before raising the pool size. If clients wait, look at slow queries first.