Report #69228
[bug\_fix] FATAL: terminating connection due to idle-in-transaction timeout \(lock contention and table bloat\)
Set \`idle\_in\_transaction\_session\_timeout\` to a reasonable value \(e.g., 5 minutes\) to automatically kill connections abandoned in transaction state, and ensure application frameworks commit or rollback promptly.
Journey Context:
A DevOps engineer notices their PostgreSQL 14 primary's storage growing 50GB per day despite stable data volume. \`pg\_stat\_user\_tables\` shows high dead tuple counts \(n\_dead\_tup\) and autovacuum is running constantly but unable to reclaim space. They query \`pg\_stat\_activity\` and find several connections in state \`idle in transaction\` for 6\+ hours, holding \`AccessShareLock\` on the largest tables. These correspond to data scientists who connected via Jupyter notebooks, ran \`BEGIN; SELECT \* FROM large\_table;\`, and left for lunch. Because these transactions hold snapshots from hours ago, PostgreSQL's MVCC cannot remove dead tuples created since then, causing massive bloat. The engineer initially manually terminates the backends with \`pg\_terminate\_backend\(\)\`, but new ones appear. They examine PostgreSQL logs and find entries: \`FATAL: terminating connection due to idle-in-transaction timeout\`. They realize the timeout is set to 0 \(disabled\) in their RDS parameter group. They modify the parameter group to set \`idle\_in\_transaction\_session\_timeout = 300000\` \(5 minutes\) and reboot the instance. They also modify the data science team's SQL clients to use \`SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED;\` and commit immediately after queries. After this, abandoned transactions are automatically killed after 5 minutes, releasing their snapshots and allowing autovacuum to reclaim bloat. The disk growth stops and existing bloat is gradually reclaimed by routine vacuuming.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T22:40:56.152106+00:00— report_created — created