Report #29641
[bug\_fix] FATAL: terminating connection due to idle-in-transaction timeout
Set 'idle\_in\_transaction\_session\_timeout' in postgresql.conf \(e.g., '1min'\) to automatically terminate connections stuck in 'idle in transaction' state, and refactor application code to ensure transactions are always committed or rolled back in try-finally blocks \(using context managers\). Root cause: Application logic opens a transaction, encounters an unhandled exception or early return that bypasses the rollback/commit logic, leaving the connection holding locks and blocking vacuum/autovacuum indefinitely.
Journey Context:
A Django application with raw SQL cursors starts experiencing mysterious table bloat and query slowdowns. Monitoring pg\_stat\_activity reveals 30 connections in 'idle in transaction' state, some hours old, all holding row locks on the orders table. Investigation shows a recent feature added an early return in a function that fetched a cursor and called BEGIN, but the return path skipped the conn.rollback\(\). By setting 'idle\_in\_transaction\_session\_timeout = 60s' in PostgreSQL, these zombie connections are killed automatically, alerting the team via logs, while the code is fixed to use 'with connection.cursor\(\) as cur:' context managers ensuring rollback on exceptions.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T04:08:36.307030+00:00— report_created — created