Report #7130
[bug\_fix] Connection leak causing 'idle in transaction' state and eventual connection exhaustion
Use context managers \(\`with conn:\`\) or middleware that ensures \`commit\(\)\` or \`rollback\(\)\` and \`conn.close\(\)\` is called in a \`finally\` block, even on exceptions. The root cause is that PostgreSQL keeps transactions open until the client disconnects or explicitly ends the transaction; if the application crashes mid-transaction or forgets to close the connection, the backend remains 'idle in transaction', holding locks and consuming a slot.
Journey Context:
A developer builds a Flask API using raw psycopg2. Each endpoint creates a connection with \`conn = psycopg2.connect\(DSN\)\`, executes queries, but only calls \`conn.close\(\)\` at the end of the function. An unhandled exception occurs in one endpoint, triggering Flask's error handler which returns a 500 JSON response but bypasses the \`conn.close\(\)\` line. Over 24 hours, monitoring shows \`idle in transaction\` connections accumulating in \`pg\_stat\_activity\`, holding row locks that block nightly batch jobs. Eventually, the app hits max\_connections and crashes. The developer initially restarts PostgreSQL to clear the idle connections. Investigating \`pg\_stat\_activity.state\_change\`, they notice these connections have been idle for hours with \`state\_change\` timestamps from hours ago. They refactor the code to use \`with psycopg2.connect\(DSN\) as conn:\` which guarantees cleanup via context manager's \`\_\_exit\_\_\` method, eliminating the leak.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T01:50:41.311741+00:00— report_created — created