Connection pool exhaustion produces silent request failures — requests queue behind a saturated pool, timeout, and return errors — with no visibility into why. CWE-400 (uncontrolled resource consumption) applies when pool limits are reached without detection. Without pool metrics, the team discovers saturation only when users report errors, not proactively when the pool approaches its limit. ISO 25010 resource-utilisation requires that resource consumption is observable; connection pool health is a critical operational signal for scaling decisions and for diagnosing connection leaks introduced by code changes.
Info because pool monitoring improves operational visibility and incident detection speed but does not prevent failures — unmonitored pools still function until they are exhausted.
Add pool event listeners to log connection activity and expose pool metrics through the /api/health endpoint. For Prisma, use the built-in $metrics API.
// pg Pool — monitor pool events
pool.on('connect', () => {
console.debug(`[pool] +1 connection. total=${pool.totalCount} idle=${pool.idleCount}`)
})
pool.on('acquire', () => {
if (pool.waitingCount > 0) {
console.warn(`[pool] ${pool.waitingCount} requests waiting — consider increasing pool max`)
}
})
pool.on('error', (err) => {
console.error('[pool] Idle client error:', err)
})
// Expose in /api/health response:
// { pool: { total: pool.totalCount, idle: pool.idleCount, waiting: pool.waitingCount } }
// Prisma metrics (4.9+)
const m = await prisma.$metrics.json()
// m.gauges: pool_active_connections, pool_idle_connections, pool_wait_count
// Forward to Datadog/Prometheus/your metrics backend
ID: database-design-operations.monitoring-ops.connection-monitoring
Severity: info
What to look for: Enumerate every connection pool and check whether connection pool health is monitored. In pg Pool: look for event listeners on connect, acquire, remove, and error events, or for code that reads pool.totalCount, pool.idleCount, pool.waitingCount. In Prisma: look for prisma.$metrics.json() usage (Prisma's built-in metrics API) or integration with an observability platform. For managed databases: look for Supabase dashboard monitoring references, AWS CloudWatch metrics for RDS connections (DatabaseConnections metric), or equivalent. Check whether pool exhaustion alerting is configured — knowing that the connection pool is saturated before requests start queuing/failing is important for scaling decisions. In serverless environments: check for Neon's connection pooler configuration or PgBouncer setup.
Pass criteria: At least 1 connection pool metric is monitored. Connection pool metrics are monitored. Either: pool event listeners log connect/error events, Prisma metrics are collected and exposed, a managed platform's dashboard is used and referenced in documentation, or pool exhaustion causes alerts. The team has visibility into connection pool health.
Fail criteria: No connection pool monitoring of any kind. Pool exhaustion would only be discovered when requests start failing. No metrics, no events, no dashboard monitoring referenced.
Skip (N/A) when: Application uses a managed database client that handles pooling transparently with no user-configurable pool (e.g., Supabase JS browser client, Firebase Realtime Database, serverless HTTP-based database drivers like Neon serverless). In these cases, the connection management is fully abstracted.
Detail on fail: Example: "pg Pool has no event listeners for connect/error events. Pool exhaustion would cause silent request failures with no visibility." or "No connection pool monitoring configured. No reference to database connection metrics in monitoring setup.".
Remediation: Add connection pool monitoring:
// pg Pool — monitor pool events
pool.on('connect', () => {
console.debug(`[pool] New connection. Total: ${pool.totalCount}, Idle: ${pool.idleCount}`)
})
pool.on('acquire', () => {
if (pool.waitingCount > 0) {
console.warn(`[pool] Connection acquired but ${pool.waitingCount} requests waiting. Consider increasing pool size.`)
}
})
pool.on('error', (err) => {
console.error('[pool] Pool error:', err)
// Alert: Sentry.captureException(err)
})
// Expose pool metrics via health check endpoint
// In /api/health: { pool: { total: pool.totalCount, idle: pool.idleCount, waiting: pool.waitingCount } }
// Prisma metrics (Prisma 4.9+)
const metrics = await prisma.$metrics.json()
// metrics.gauges includes pool_active_connections, pool_idle_connections, pool_wait_count
// Send to your metrics backend (Datadog, Prometheus, etc.)
For managed databases, document which platform dashboard to check for connection metrics:
Connection monitoring: Supabase Dashboard > Settings > Database > Connection Pooler
Check for: active connections, pool size, wait queue length