Postgres connection pooler
Small servers often run out of Postgres connections before they run out of CPU or memory. Each app replica opens its own pool, andmax_connections fills up fast. A managed Postgres database can opt into a pooler: a pgbouncer style container that runs next to the database in transaction pooling mode, so many client connections share a few server connections.
Enable it
The control plane needs to know which pooler image to run. There is no built in default, so you pick and pin a version you trust:
The two sizing variables are control plane defaults. A single database can override them with
--pool-size and --max-client-conn (CLI), the sizing inputs on the pooler card, or pooler.pool_size and pooler.max_client_conn in a resource file. 0 or unset keeps the default. Changing them replaces the pooler container.
Then turn it on per database:
GET, POST and DELETE on /api/v1/databases/{name}/pooler. Reading needs the read ability; toggling needs the sensitive write ability, the same as public access, since it changes the URL every linked app receives.
What changes for apps
The pooler joins the database container’s network namespace and listens on port 6432. Apps keep the same host, only the port changes.{ from: { database: main, field: url } }resolves to the pooled URL while the pooler is on.field: portresolves to 6432 while the pooler is on.field: direct_urlalways resolves to the direct Postgres URL. Use it for migrations,LISTEN/NOTIFY, advisory locks held across transactions, and anything else that needs a session.
SET without LOCAL, and temporary tables can misbehave on the pooled URL. Most ORMs have a setting for this (for example disabling server side prepared statements).
How it is reconciled
The reconciler treats the pooler as a child of the database and converges it on every pass:- Enabled and the database is running: the pooler container exists and runs. It is recreated when the database container is replaced (a version change), the image changes, or the pool settings change.
- Disabled, suspended or deleted: the pooler container is removed.
- Its health shows up as a separate
PoolerReadycondition, so a broken pooler never marks the database itself as down.pooler showprints the reason, for examplePoolerImageNotConfigured.
pooler show use a <password> placeholder.