Each PostgreSQL connection consumes server resources and can hold transaction state, locks, prepared statements, and session settings. Pooling reuses a controlled number of connections; it does not create database capacity. A connection budget must cover all application replicas, workers, migrations, administrators, monitoring, failover headroom, and AI concurrency without exhausting the server.
Pool size is multiplicative:
A pool protects PostgreSQL only if callers wait under bounded backpressure instead of creating more pools.
Set meaningful application_name. Monitor active, idle, idle-in-transaction, wait time, checkout latency, timeouts, and saturation.
Session pooling preserves session state. Transaction pooling assigns a server connection per transaction, so session-level features and prepared statements may require driver/pooler-specific handling. Do not assume compatibility; test exact versions and modes.
Prepared statements reduce parse/plan overhead and provide parameters, but PostgreSQL may choose custom or generic plans whose performance differs with skew. Parameters prevent injection; preparation alone does not authorize a query.
Streaming chat endpoints and parallel agent tools can pin application tasks. Do not hold database connections while streaming tokens or waiting on models. Fetch bounded context, release, call the model, then reacquire for a short validated write. Apply per-request tool and database concurrency limits.
Write a budget table for normal, peak, one-replica-failure, and failover scenarios. Load test pool checkout and database active connections. Force pool saturation in an isolated environment and prove callers fail or queue within a declared timeout rather than cascading indefinitely.
Budget SignalDesk for 6 API replicas, 4 workers, two migration connections, monitoring, and admin reserve under a 100-connection ceiling.
Acceptance criterion: totals fit with failure headroom and no connection is held through model generation.