infra/ansible/roles/pgbouncer
2026-05-20 12:06:54 -05:00
..
defaults updates 2026-05-20 12:06:54 -05:00
handlers updates 2026-05-20 12:06:54 -05:00
tasks updates 2026-05-20 12:06:54 -05:00
templates updates 2026-05-20 12:06:54 -05:00
README.md updates 2026-05-20 12:06:54 -05:00

pgbouncer

Installs and configures PgBouncer on a PostgreSQL host. PgBouncer fronts the local backend and bounds the number of real backend connections per database, so one app can't exhaust the server's max_connections and starve its neighbours.

How it works

  • Listens on :6432 (apps point DATABASE_URL there instead of :5432).
  • Clients authenticate to PgBouncer; PgBouncer resolves each role's verifier at connect time via auth_query against a SECURITY DEFINER lookup function, so no per-app passwords live in this repo.
  • Default pool_mode is session — safe for Ecto/Postgrex prepared statements and Oban's LISTEN/NOTIFY. Override to transaction per database only for apps verified to tolerate it.

Required variables

Set in the DB host's host_vars and vault:

# vault
vault_pgbouncer_auth_password: "<random>"

# host_vars
pgbouncer_databases:
  - { name: towerops }                       # session mode (default)
  - { name: aprsme_prod, pool_size: 30 }
  - { name: prop, pool_mode: transaction }   # opt-in transaction pooling

Cutover

  1. Apply the role, then verify: psql -h <host> -p 6432 -U <user> <db> -c 'select 1'.
  2. Repoint each app's DATABASE_URL host/port to the PgBouncer listener.
  3. Inspect pools from the admin console: psql -h <host> -p 6432 -U pgbouncer pgbouncer -c 'SHOW POOLS'.