Report #66493
[bug\_fix] idle in transaction \(state in pg\_stat\_activity causing lock contention\)
Set \`idle\_in\_transaction\_session\_timeout = 60000\` \(milliseconds\) in postgresql.conf or via \`ALTER SYSTEM\` to automatically terminate sessions idle in transaction for more than 60 seconds. Additionally, fix application code to ensure \`commit\(\)\` or \`rollback\(\)\` is always called in \`finally\` blocks or context managers \(try-with-resources, Python contextlib, etc.\) to prevent connection leaks.
Journey Context:
Developer notices that nightly VACUUM jobs are failing with 'waiting for lock', and simple updates hang indefinitely. Querying \`pg\_stat\_activity\` reveals multiple connections with \`state = 'idle in transaction'\` and \`xact\_start\` timestamps from hours ago. These connections are holding back the xmin horizon, preventing dead tuple cleanup and causing table bloat. Investigating the application logs, the developer finds that a recent change in a background job worker throws an exception after starting a transaction but before the commit. The exception is caught and logged, but the connection is returned to the pool still holding the transaction open. The immediate fix is setting \`idle\_in\_transaction\_session\_timeout\` to kill these zombies. The permanent fix is refactoring all database calls to use context managers that guarantee rollback/commit in a \`finally\` block.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T18:05:27.434013+00:00— report_created — created