Database Connections, Pooling, and Capacity
Pathrule3 Rules • 2 Memories • 1 Skill
Connection pools multiply across every application replica, worker process, background consumer, migration job, and deployment overlap, so a locally reasonable maximum can exhaust the database before traffic reaches application CPU limits. This pattern constrains pool budgets, acquisition deadlines, and connection cleanup; it records transaction-pooler and deployment behavior and provides a capacity and leak investigation procedure. It complements query performance and database transactions by focusing on admission and session resources before SQL execution begins.
Suggested path map
Pathrule places each piece on the matching path, so your assistant only sees it where it belongs. This is the scoping you get on import; you can adjust it in your workspace.
Rules
3Budget pools from database capacity across the whole fleet/infrahighstrictReserve administrative headroom, then divide safe connections among replicas, workers, jobs, migrations, and deployment overlap.
| 1 | A pool maximum applies to one process or runtime instance. Autoscaling and rolling deployments multiply it, and background services often share the same database without appearing in the web-service configuration. |
| 2 | |
| 3 | - Inventory every process type that can connect, its maximum replicas or concurrency, number of pools, and whether old and new versions overlap during deployment. |
| 4 | - Reserve capacity for administration, monitoring, maintenance, failover, and a degraded state rather than assigning the database maximum to application pools. |
| 5 | - Set per-process pool limits from the fleet budget and dependency concurrency, then cap autoscaling where connection capacity is the hard limit. |
| 6 | - Recalculate after adding workers, tenants with dedicated databases, read replicas, or new deployment environments; pool capacity is infrastructure design, not a library default. |
| 7 | |
| 8 | See /src/db for the adjacent decision or procedure that completes this constraint. |
Bound connection acquisition and always release ownership/src/dbhighstrictUse an acquisition deadline, scope checkout to the smallest database operation, and release or discard connections on every outcome.
| 1 | When the pool is exhausted, callers can wait indefinitely and consume request or job concurrency while the database sees no new statement. Error, timeout, and cancellation paths are where leaked ownership accumulates. |
| 2 | |
| 3 | - Set an acquisition timeout shorter than the caller's total deadline and return a capacity-specific failure with pool wait evidence. |
| 4 | - Use structured transaction or connection helpers that release in a finalization path after success, rollback, error, and cancellation. |
| 5 | - Do not keep a connection checked out while performing HTTP calls, user think time, queue waits, large file work, or computation that can occur outside the database boundary. |
| 6 | - Discard connections the driver marks broken or whose session reset cannot be proven; returning a poisoned session to the pool spreads one failure across callers. |
| 7 | |
| 8 | See /ops/runbooks for the adjacent decision or procedure that completes this constraint. |
Reset session state before reuse/src/dbhighstrictKeep timezone, role, search path, temporary objects, variables, and transaction state from leaking between unrelated borrowers.
| 1 | A pooled connection is a reused session. State set by one request can silently affect the next request unless it is transaction-local, explicitly reset, or prohibited by the pooling mode. |
| 2 | |
| 3 | - Prefer transaction-local settings for tenant, role, timeout, and tracing context so commit or rollback clears them automatically. |
| 4 | - Never return a connection with an open or failed transaction; roll back and verify clean state in the connection wrapper. |
| 5 | - Avoid temporary tables, prepared-statement assumptions, and session variables when a transaction pooler can route successive transactions to different server sessions. |
| 6 | - Test two callers sequentially on one pool connection with different tenants, roles, timezones, and failures to prove state isolation. |
| 7 | |
| 8 | See /infra for the adjacent decision or procedure that completes this constraint. |
Memories
2Pool wait and query time are separate signals/src/dbMeasure acquisition, transaction, execution, result transfer, and release so capacity problems are not misdiagnosed as slow SQL.
| 1 | An endpoint can spend most of its latency waiting for a connection while the eventual statement executes quickly. Looking only at database query duration hides the admission queue in the application. |
| 2 | |
| 3 | - Record pool size, idle, checked out, waiters, acquisition duration, timeouts, and connection errors per process and aggregate them across the fleet. |
| 4 | - Trace acquisition as a separate span or phase from SQL execution and attach the logical operation without logging raw sensitive parameters. |
| 5 | - Correlate wait growth with replica count, request concurrency, long transactions, database CPU and I/O, and deployment overlap. |
| 6 | - Alert on sustained saturation and wait percentiles before every caller reaches its timeout and begins retrying simultaneously. |
| 7 | |
| 8 | See /ops/runbooks for the rule or workflow that puts this decision into practice. |
External poolers change the session contract/infraChoose session, transaction, or statement pooling from application behavior and validate driver features against that mode.
| 1 | A transaction pooler improves multiplexing by assigning a server session only for a transaction, but application code cannot assume the same session handles later work. Some prepared statements, temporary objects, locks, and variables depend on that continuity. |
| 2 | |
| 3 | - Document the selected pooling mode and which session features are prohibited or require driver-specific configuration. |
| 4 | - Keep each unit of consistency in one explicit transaction so a transaction pooler cannot split related statements across sessions. |
| 5 | - Size application-side pools as concurrency queues even when an external pooler exists; removing all local bounds can overwhelm the pooler with clients. |
| 6 | - Test failover, pooler restart, server connection recycling, and prepared-statement behavior under the exact driver and deployment configuration. |
| 7 | |
| 8 | See /src/db for the rule or workflow that puts this decision into practice. |
Skills
1investigate-pool-exhaustion/rootSeparate fleet budget, pool wait, leaked ownership, long transactions, and database saturation in a connection incident.
| 1 | --- |
| 2 | name: investigate-pool-exhaustion |
| 3 | description: Investigate database connection exhaustion, acquisition timeouts, or sudden pool wait growth. |
| 4 | --- |
| 5 | |
| 6 | # Investigate Pool Exhaustion |
| 7 | |
| 8 | Run this procedure when the affected surface changes, before the result is promoted to production. Record evidence for every step instead of accepting a plausible-looking result. |
| 9 | |
| 10 | 1. Capture fleet replica counts, deploy overlap, pool configuration, active and idle connections, waiters, database limits, and administrative headroom. |
| 11 | 2. Separate acquisition time from SQL execution and identify processes, endpoints, jobs, or tenants with the longest checked-out duration. |
| 12 | 3. Trace representative connection ownership through transaction, error, cancellation, streaming, and remote-call paths to find unreleased or unnecessarily held sessions. |
| 13 | 4. Reduce intake or concurrency before increasing pool size; confirm the database has CPU, memory, and lock capacity for any additional active work. |
| 14 | 5. Reproduce the dominant leak or saturation path, add a regression test and ownership evidence, then verify waits and timeouts recover across a rolling deployment. |
| 15 | |
| 16 | ## Exit criteria |
| 17 | |
| 18 | The change is complete only when the expected behavior, failure behavior, and rollback path have all been exercised with representative data. Preserve the evidence with the change so the next operator can repeat the same checks. |
Why this pattern
AI agents often set a pool maximum per process without multiplying replicas, hold connections during remote calls, or mistake pool wait time for slow SQL.
Built for Backend and platform teams operating relational databases behind autoscaled services and workers.
Keeps your assistant from:
- Exceeding database connection capacity during scale-out or rolling deploy
- Leaking checked-out connections on error and cancellation paths
- Holding a connection while waiting on unrelated remote I/O
- Using session features through a transaction pooler that cannot preserve them
- License
- Apache-2.0
- Version
- 1.0.0
- Updated
- 2026-08-25