Connection pools
0-day streakReview

Your progress

Level 1

0 XP100 XP to level 2
0day streak
0best streak
0topics started
0cards reviewed
    Review cards

    Progress is stored only in this browser. No account is required.

    Connection pooling: the 60-second story

    Connection pooling

    Six round trips before your first query.

    TCP, TLS and SCRAM, then PostgreSQL forks a process. About 6 ms in one zone, 360 ms across regions. Pay it once, not per request.

    A pool lends a few open connections and queues the rest

    Borrow, run, return. When all are busy, callers wait; past the checkout timeout they get an error instead.

    100% CPU. Add connections?

    Bad: Raise max_connections to 5,000

    Same cores. The extra queries just queue inside the database.

    Good: Shrink the pool

    One demo cut 2,048 connections to 96: 100 ms became 2 ms.

    4,000

    connections from 200 pods with pools of 20

    That’s 40 times PostgreSQL’s default limit of 100, and autoscaling adds pods exactly when the database is busiest.

    PgBouncer in transaction mode: 4,000 clients, 40 server connections

    Most web connections sit idle between transactions, so PgBouncer lends a server connection per transaction, not per session.

    With transaction pooling on, client A runs SET on server connection 1, then commits.

    The catch

    Client C’s next transaction lands on that connection and inherits A’s setting. Use SET LOCAL, or ALTER ROLE … SET.

    Size it with Little’s law

    1. Busy connections = queries/s × hold time
    2. 5,000/s × 4 ms = 20 busy
    3. Add headroom, about 30 in total
    4. Cross-check: cores × 2 + spindles

    A slow database drains the pool in half a second

    Queries slow from 4 to 400 ms. The pool now serves 50 requests a second; 450 queue, and 200 threads block in 0.44 s.

    Remember

    Never connect per request. Size the pool with Little’s law, funnel pods through PgBouncer, and fail fast when it’s empty.