Pool Modes and Sizing
Understand session, transaction, and statement pooling in pgbouncer — their trade-offs, caveats, and how to size the pool for your Postgres.
Most teams bolt pgbouncer in front of Postgres and leave it in session mode. This course shows you exactly what each pool mode does to your server connections and why the choice matters. We build a two-service stand — Postgres with a deliberate connection cap and pgbouncer in front — and walk every mode hands-on: how server connections are assigned in session mode, how transaction mode multiplexes thirty clients through five server slots, and why statement mode breaks ordinary transactions. Then we face the caveats that catch engineers off guard: session-level SET parameters that vanish after a reconnect, prepared statements that disappear between transactions, and temporary tables that evaporate mid-session. We finish with the sizing knobs — default_pool_size, max_client_conn, reserve_pool_size — and the pgbouncer admin console commands you reach for whenever something looks wrong.
What you'll build
- Explain what session, transaction, and statement pooling each do to server connections
- Switch pool_mode and reload pgbouncer without dropping connections
- Explain why SET, prepared statements, and temp tables can break in transaction pooling
- Configure max_client_conn, default_pool_size, and reserve_pool_size
- Read SHOW POOLS, SHOW STATS, and SHOW CLIENTS to diagnose a saturated pool
- Describe the correct app → pgbouncer → Postgres connection architecture
Contents
- Two services, one course
- Two services, declared
- Cap the connections on purpose
- Authentication the simple way
- The three knobs that matter most
- The table we run queries against
- Deterministic data, every time
- Start the stand
- Connect directly to Postgres
- Load the schema and seed the data
- Confirm the data is there
- Session pooling: one client, one server slot
- Session state lives in the connection
- SET survives in session mode
- Spawn multiple clients at once
- Five unique backends, five reused
- SHOW POOLS: the heartbeat of the pooler
- Reading a quiet pool
- One line changes everything
- Reload without dropping connections
- Confirm the new mode
- A simple load script
- Ten clients, five server connections
- Many clients, few backends
- The caveat that surprises most teams
- SET in a single connection — works fine
- Within one connection, SET holds
- A new connection gets the default
- Prepared statements and transaction pooling
- Temporary tables are session objects
- A checklist to read before you migrate
- Statement mode — the most aggressive option
- Reload into statement mode
- Multi-statement transactions are forbidden
- Back to transaction mode
- How to size a pool
- Double the pool, add a reserve
- Apply the sizing change
- More server connections, fewer waiters
- SHOW STATS — throughput at a glance
- SHOW CLIENTS — inspect individual connections
- Inspect active client connections
- The server side: pg_stat_activity
- The anti-pattern: connecting directly at scale
- The right architecture
- SHOW CONFIG — read the live configuration
- The production checklist
- The stand at rest