Skip to main content

Runbook: database pool

Alerts: HikariPoolNearExhaustion, HikariPoolExhausted, HikariAcquireSlow, PostgresConnectionsHigh, PgBouncerClientsWaiting, JdbcP95High.

Symptoms​

Timeouts on one service, health flipping, other services fine. That pattern is a pool or a slow query in one schema, not "Postgres is down". If every service times out together, look at the host and PgBouncer.

Check​

  1. Which service's pool is exhausted.
  2. Active queries in that schema: a missing index on a new filter, a lock from a long transaction, an inbox worker and the API sharing one small pool.
  3. PgBouncer waiting clients. If the pooler waits and Postgres is idle, the pooler config is the limit.
  4. Deploy correlation. A new query shape usually arrives with a release.

Repair​

  • Kill a single runaway query if you can name it and it is not a migration.
  • Scale the pool only after you know the query is legitimate. A larger pool on a saturated database makes it worse.
  • Add the index in a Flyway migration in the owning service. Do not CREATE INDEX by hand on production and forget the migration.
  • Restart the service if connections are leaked and you cannot find the holder. Then file the leak.

The relay uses its own pool (OUTBOX_HIKARI_MAXIMUM_POOL_SIZE). Do not steal API connections for it.