Report #17754
[bug\_fix] idle in transaction \(long-running idle transaction causing bloat/locks\) in PostgreSQL
Set the GUC parameter 'idle\_in\_transaction\_session\_timeout' to a reasonable value \(e.g., 5 minutes\) to automatically terminate idle sessions. Additionally, fix application code to ensure transactions are committed or rolled back immediately after work completes, especially in web frameworks that may leave transactions open across request boundaries. Root cause: Idle transactions hold back the xmin horizon, preventing vacuum from removing dead tuples, causing table/index bloat and eventually transaction ID wraparound risks.
Journey Context:
A SaaS platform notices steady growth in database storage despite constant user count; pg\_stat\_user\_tables shows n\_dead\_tup in the millions for the users table, and autovacuum is running but unable to reclaim space. The DBA queries pg\_stat\_activity and finds 30 connections in 'idle in transaction' state, some hours old, from the application servers. Investigation reveals a Ruby on Rails controller that raises an exception but is caught by a rescue block that logs the error but doesn't rollback the transaction, leaving it open. The DBA sets 'idle\_in\_transaction\_session\_timeout = 300000' \(5min\) as a safety net, causing those idle sessions to be killed and vacuum to proceed. The devs fix the rescue block to ensure 'transaction.rollback' is called, resolving the root cause.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T06:18:34.190366+00:00— report_created — created