fix(config): keep no PostgreSQL connection warm by default, idle timeout back to 10 s
Merged
EV
9d ago+58+58+01234567890123456789-20-20-01234567890123456789
Why
Stage API (apistage.gauzy.co) stalled after the develop → stage promotion 61d0d6750a rolled out at 15:42Z.
- #10976 (
38988ff788) changed the defaults toDB_POOL_MIN2 andDB_IDLE_TIMEOUT30 s. That was measured on a direct PostgreSQL connection. - Hosted stage and production reach PostgreSQL through a session-mode PgBouncer. There, every open client connection, idle or not, holds one server connection.
- On stage that pooler has 4 server connections per instance (12 in total), shared by the API, the worker and the Teams API.
gauzy_stagesat at 12/12. New client connections waited in PgBouncer for up to 98 s (cnpg_pgbouncer_pools_maxwait). - In the API logs this looked like slow queries:
SELECT version()67 s at boot,timesheet/statistics/counts94 s.
Change
DEFAULT_DB_IDLE_TIMEOUT_MS30000 → 10000, and a newDEFAULT_DB_POOL_MIN= 0 (was a literal 2).- Both env knobs stay. A direct connection or a transaction-mode PgBouncer can opt in to
DB_POOL_MIN=2andDB_IDLE_TIMEOUT=30000. The doc comment onDEFAULT_DB_IDLE_TIMEOUT_MSand.env.samplesay when that is safe. - Unchanged: keep-alive,
application_name, the opt-in server-side timeouts, and the MikroORM / Knex pools (min 0 already). - Specs updated: the defaults test now expects min 0 and 10 s, the opt-in test covers min 2 and 30 s, an invalid
DB_POOL_MINfalls back to 0, and the startup log line readsDB Idle Timeout: 10000. - Prettier also re-wrapped one existing line (
DB_KEEP_ALIVEcheck) indatabase.ts. Formatting only.
Agreed with the author of #10976 (the perf session), who asked for the session-pooler note.
Verification
packages/config/src/lib/database-config-validation.spec.ts: 60/60 pass;tsc -p packages/config/tsconfig.lib.jsonclean.- The same two values are already live on stage as env overrides via ever-co/k8s-gitops#219, so the stage API recovers before this PR reaches stage.
Rollout
develop → stage only. Owner rule: no stage → master for now. Prod's pooler is also session mode, so this has to land before #10976 ever reaches master.
🤖 Generated with Claude Code
Summary by cubic
Reverts the default PostgreSQL pool settings so no connection is kept warm and idle ones close after 10 s, preventing the API from stalling when PostgreSQL is reached through a session-mode PgBouncer.
- #10976 raised the defaults to
DB_POOL_MIN=2and 30 s idle timeout, measured against a direct connection; behind a session-mode PgBouncer every open client connection holds a server connection, which saturated the stage pooler (12/12) and made new connections wait up to 98 s. - The defaults are back to min 0 and 10 s; direct connections and transaction-mode PgBouncers can opt in via
DB_POOL_MIN=2/DB_IDLE_TIMEOUT=30000. DB_POOL_MINapplies to the active ORM's pool only; the Knex pool always keeps none.- Unchanged: keep-alive,
application_name, and the opt-in server-side timeouts.
Migration
- Re-deploy stage only;
DB_POOL_MIN=2andDB_IDLE_TIMEOUT=30000must not reach the session-mode pooler, so this has to land before #10976 reaches master.