Load balancer

autopg-pool is the second half of autopg: a connection pooler that sits in front of Postgres. It is a thin, opinionated wrapper around pgbouncer that trades pgbouncer's scattered config files for one TOML file and environment variables.

Why a pooler

Postgres assigns a backend process to every connection, so a few hundred idle connections can cost real memory and scheduling overhead. Web apps and serverless functions tend to open far more connections than the database should hold at once. A pooler keeps a small set of warm server connections and multiplexes your many client connections onto them. That is the difference between a database that falls over under a traffic spike and one that absorbs it.

What autopg-pool is

Under the hood it is pgbouncer, built from source and pinned to a known version. What autopg-pool adds is the deployment ergonomics pgbouncer leaves to you:

  • One TOML file instead of pgbouncer.ini, userlist.txt, and pgbouncer_hba.conf. autopg-pool generates all three from your TOML.
  • Secrets from the environment. Reference $VARIABLE in the TOML and it is filled in from the container environment, so credentials stay out of the config.
  • Hashes computed for you. MD5 password hashes are calculated automatically. There is no pgbouncer_setpwd step.
  • Opinionated defaults for the settings that matter, like an idle transaction timeout to stop a stuck client from saturating the pool.

Running it

The image is published alongside the Postgres image:

ghcr.io/piercefreeman/autopg-pool:latest

Mount your config and pass the secrets it references:

services:
  pool:
    image: ghcr.io/piercefreeman/autopg-pool:latest
    ports:
      - 6432:6432
    environment:
      - APP_PASSWORD=changeme
      - MAIN_DB_PASSWORD=changeme
    volumes:
      - ./autopgpool.toml:/etc/autopgpool/autopgpool.toml
    restart: unless-stopped

Your application connects to the pooler on port 6432 instead of connecting to Postgres directly. See Configuration for the full TOML reference.

How requests flow

  1. A client connects to autopg-pool on 6432 and authenticates as one of the users you declared.
  2. autopg-pool checks the user's grants to confirm it may reach the requested pool.
  3. The pool maps to an upstream Postgres defined under [pools.<name>.remote].
  4. The request runs on one of the warm server connections in that pool, then the connection returns to the pool according to the pool mode.

Because users, grants, and upstreams are all declared in one file, the routing is easy to read and review.