Skip to content

Diagnosing PgBouncer's max_client_conn limit

Covers PgBouncer's own client-facing connection ceiling — a different limit from Postgres's max_connections and from PgBouncer's server-side pool sizing. Does not cover prepared-statement errors under transaction pooling (see the two prepared-statement playbooks) or Postgres running out of connections directly (see the postgres-too-many-clients playbook).

Unverifiedno reproductions yetWhy this confidence?
Revision 1published by DevYou curationrevision history
Run the diagnosisEvidence and compatibility

Symptoms

The diagnostic path

8 steps. Every step is written out below in full — the interactive version simply follows the branches for you.

  1. Step 1 · StartPgBouncer is refusing new client connections

    This is PgBouncer's own max_client_conn — the number of frontend (application-side) connections it will accept — not Postgres's max_connections, and not PgBouncer's server-side pool size (default_pool_size / max_db_connections). Those are three independent limits.

    What happens next

    • passed step 2, Check current clients against the configured limit
  2. Step 2 · TestCheck current clients against the configured limit

    Connect to PgBouncer's admin console — not a normal database — with psql -h <pgbouncer-host> -p <pgbouncer-port> -U <admin-user> pgbouncer, then run:

    Read-onlysql
    SHOW CLIENTS;

    Expected result

     type |   user   | database |  state |   addr      | port  | ... 
    ------+----------+----------+--------+-------------+-------+-----
     C    | appuser  | appdb    | active | 10.0.4.12   | 51422 | ...
     C    | appuser  | appdb    | active | 10.0.4.19   | 51501 | ...
    (2000 rows)

    What happens next

    • passed step 3, Break the client count down by pool
    • failed step 4, Not actually at max_client_conn
    • unknown step 4, Not actually at max_client_conn
  3. Step 3 · ObservationBreak the client count down by pool

    SHOW POOLS gives a per-database/user summary with active and waiting client counts, which is faster to reason about than scrolling SHOW CLIENTS when there are thousands of rows.

    Read-onlysql
    SHOW POOLS;

    Expected result

     database | user    | cl_active | cl_waiting | sv_active | sv_idle | ... 
    ----------+---------+-----------+------------+-----------+---------+-----
     appdb    | appuser |      2000 |        340 |        20 |       0 | ...
    (1 row)

    What happens next

    • passed step 5, Client connections are consistently at the ceiling
  4. Step 4 · EndNot actually at max_client_conn

    If the client count found above is nowhere near the configured limit, this specific message isn't what's happening right now — check for a different error (e.g. Postgres's own too-many-clients, or a prepared-statement error) instead.

  5. Step 5 · Root causeClient connections are consistently at the ceiling

    Common causes: many application instances or serverless/edge functions each opening their own connections without reuse, a client-side connection leak (never closed), or max_client_conn genuinely undersized for the current fleet. PgBouncer accepting thousands of client connections cheaply while multiplexing them onto a much smaller server-side pool is the entire point of running it — so raising the client limit is usually safe as long as the server-side pool size is left alone.

    What happens next

    • passed step 6, Raise max_client_conn and reload without dropping connections
  6. Step 6 · FixRaise max_client_conn and reload without dropping connections

    Edit max_client_conn in pgbouncer.ini (e.g. to 2000), then apply it with the admin console's RELOAD command rather than restarting the process.

    Changes statesql

    Changes system or service state. Review before running.

    Reloads pgbouncer.ini into the running process, applying the new max_client_conn (and any other edited settings) immediately, without dropping existing client or server connections.

    RELOAD;

    What happens next

    • passed step 7, Confirm the new limit took effect and there's headroom
  7. Step 7 · Verify the fixConfirm the new limit took effect and there's headroom

    Check the config value directly.

    Read-onlysql
    SHOW CONFIG;

    Expected result

     key             | value | changeable 
    ------------------+-------+------------
     max_client_conn  | 2000  | yes
    (1 row)

    What happens next

    • passed step 8, Resolved
    • failed step 5, Client connections are consistently at the ceiling
    • unknown step 5, Client connections are consistently at the ceiling
  8. Step 8 · EndResolved

    maxclientconn now reflects real client demand with headroom. If the underlying cause was a leak rather than genuine growth, raising the limit buys time but doesn't fix the leak.

Sources

Why this confidence?

What would strengthen it: 6 more independent reproductions. Reproductions from 3 more distinct environments.