pgAgroal Enterprise · How-to
Migrate from PgBouncer
Replacing PgBouncer is a practical blocker for many teams: you already have a pgbouncer.ini with routing and auth assumptions to understand before you can move. The Enterprise pgbouncer-import tool converts that configuration into pgagroal config and produces a human-readable migration report — so the move is a reviewed translation, not a guess.
What the tool does
pgbouncer-import reads a pgbouncer.ini and writes two things: a translated pgagroal.conf and a migration report. It never silently drops or guesses settings.
- Translates the safe
[pgbouncer]keys into pgagroal configuration. - Maps compatible pool modes to pgagroal pipeline behaviour.
- Parses
[databases]entries and reports the routing implications. - Reports unsupported keys explicitly, so you decide rather than the tool guessing.
- Requires no change to pgagroal itself.
Convert your config
Point the tool at your pgbouncer.ini, writing the config and report to files:
pgbouncer-import -o pgagroal.conf -report migration-report.txt pgbouncer.iniWith no -o the config goes to stdout; with no -report the report goes to stderr. Pass - as the path to read from stdin, which is handy in a pipeline:
cat /etc/pgbouncer/pgbouncer.ini | pgbouncer-import - > pgagroal.confReview the migration report
Read the report before deploying. It lists what was translated, what needs a manual decision, and the backend/database routing it derived. Anything the report flags as unsupported is a deliberate prompt for you to choose an equivalent in pgagroal rather than an assumption baked into the output.
pgagroal.conf as a reviewed starting point, not a drop-in replacement.Worked example
This shows a small pgbouncer.ini, the pgagroal.conf the tool writes from it, and the part of the report that asks you to decide something. Map the shape onto your own file rather than the exact values.
Input: pgbouncer.ini
PgBouncer keeps its settings in an INI file. The [databases] block lists which database each client name routes to; the [pgbouncer] block holds pooler settings.
[databases]
appdb = host=db1.internal port=5432 dbname=appdb
[pgbouncer]
listen_port = 6432
max_client_conn = 500
pool_mode = transaction
default_pool_size = 20
so_reuseport = 1Output: pgagroal.conf
The tool writes a [pgagroal]section (the pooler’s own settings) and a derived [primary] backend (where the pooler connects upstream, taken from the [databases] entry).
[pgagroal]
port = 6432
max_connections = 500
pipeline = transaction
# (other pgagroal defaults omitted)
[primary]
host = db1.internal
port = 5432listen_port = 6432becomesport = 6432in[pgagroal].max_client_conn = 500becomesmax_connections = 500.pool_mode = transactionbecomespipeline = transaction(andpool_mode = sessionbecomespipeline = session).- The
appdbline in[databases]becomes the derived[primary]backend withhost = db1.internal.
Migration report excerpt
The report is plain text. Its exact layout may differ, but it conveys what was translated, the backend it derived, and what it could not translate — the last group is a list of decisions for you, not settings the tool silently dropped:
Translated:
listen_port = 6432 -> [pgagroal] port = 6432
Derived backend:
appdb = host=db1.internal ... -> [primary] host = db1.internal
Unsupported (manual decision required):
so_reuseport = 1 -> no pgagroal equivalent;
decide whether you still need itdefault_pool_size and min_pool_size are translated as-is (same key name, value copied unchanged), and auth_file becomes users_file. auth_type, auth_query, and auth_user have no pgagroal equivalent: they are listed under Unsupported, and the report adds a warning that tells you to set the authentication method in pgagroal_hba.conf (plus a users file for non-trust auth, or allow_unknown_users for transparent passthrough).Setting mapping
How the settings a typical pgbouncer.ini contains line up with pgagroal. Anything without a clean equivalent is listed in the report for you to decide.
| pgbouncer.ini | pgagroal equivalent | Notes |
|---|---|---|
listen_port | port (in [pgagroal]) | Port the pooler accepts client connections on. |
max_client_conn | max_connections | Cap on total client connections to the pooler. |
pool_mode | pipeline | transaction and session map across by name; how aggressively connections are reused. |
[databases] entry | Derived [primary] backend | The host= of the entry becomes the backend the pooler connects to. |
default_pool_size / min_pool_size | default_pool_size / min_pool_size | Translated as-is — same key name, value copied unchanged. |
auth_file | users_file | Path to the credentials file is translated. |
auth_type / auth_query / auth_user | None | No equivalent; reported as Unsupported with a warning to configure pgagroal_hba.conf (and a users file, or allow_unknown_users for passthrough). |
Unknown keys (e.g. so_reuseport) | None | Not translated; listed in the report as a manual decision. |
Cut over safely
The generated config is a reviewed starting point, not a guaranteed drop-in. Move in steps so you can fall back at any point.
- Run in parallel. Deploy pgagroal alongside your existing PgBouncer rather than replacing it. Both poolers can front the same database while you validate.
- Switch the connection string.Point your application’s connection string from the PgBouncer endpoint to the pgagroal pooler Service. Change one consumer first, not all of them at once.
- Keep a rollback ready. To roll back, point the connection string back at PgBouncer. Because both run in parallel, rollback is a config change with no redeploy of the database.
SET, prepared statements, advisory locks — can behave differently after the switch. Test under realistic load before cutting over, and see Connection pooling for the pooling-mode trade-offs.Next steps
- Roll the generated config into a deployment with the Helm install.
- Register the pooler’s users and source their credentials — see Manage users & credentials and Resolve secrets from a Secrets Manager.
- For the full pgagroal configuration reference, see the pgagroal manual.