Report #61327
[bug\_fix] Postgres idle in transaction blocking vacuum
Set idle\_in\_transaction\_session\_timeout = '5min' \(or lower\) to automatically kill hanging connections; fix application logic to commit/rollback before calling external services or user input; use autocommit for read-only queries. Root cause: Postgres uses MVCC with xmin/xmax transaction IDs; an idle-in-transaction backend holds back the xmin horizon, preventing vacuum from removing dead tuples, causing table/index bloat and eventually transaction ID wraparound issues.
Journey Context:
A SaaS platform notices gradual performance degradation over months. Table sizes are 3x expected despite stable row counts. Vacuum logs show 'oldest xmin is 123456789, age is 5000000'. Checking pg\_stat\_activity reveals 3 connections in 'idle in transaction' state for 6\+ hours, started by a background job that called a slow external API then crashed without rollback. The DBA terminates those backends; vacuum immediately reclaims 200GB. To prevent recurrence, they set idle\_in\_transaction\_session\_timeout = '10min' in postgresql.conf and refactor the job to use short transactions.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T09:25:11.647856+00:00— report_created — created