Report #14785
[bug\_fix] idle in transaction \(connection leak leading to eventual 'too many clients'\)
Set the PostgreSQL configuration parameter \`idle\_in\_transaction\_session\_timeout\` to a non-zero value \(e.g., '1min'\) to automatically terminate connections that remain idle in a transaction block for longer than the threshold. Additionally, fix application exception handling to ensure \`ROLLBACK\` is called in \`ensure\`/\`finally\` blocks. Root cause: Application code starts a transaction, encounters an unhandled exception or early return, and fails to commit or rollback, leaving the connection in an 'idle in transaction' state indefinitely.
Journey Context:
Our API server \(Go with lib/pq\) slowly exhausted its database connection pool over 48 hours, requiring restarts. Monitoring \`pg\_stat\_activity\` revealed dozens of connections in the \`idle in transaction\` state, some hours old, all originating from a specific microservice. Tracing the code, we found a background goroutine that fetched jobs from a queue inside a \`BEGIN\` block. If the job processing panicked, the \`defer\` only logged the error but never called \`Rollback\(\)\`. The connection was returned to the pool with an open transaction, never to be closed. We immediately set \`idle\_in\_transaction\_session\_timeout = 60000\` \(60 seconds\) in postgresql.conf as a safety net, causing Postgres to terminate these leaked connections automatically with a log message. Then we fixed the Go code to use \`defer tx.Rollback\(\)\` immediately after \`Begin\(\)\`, ensuring rollback happens even on panic. The connection leak stopped permanently.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T22:23:38.268801+00:00— report_created — created