idle_in_transaction_session_timeout
Terminates a session that has an open transaction but is genuinely idle (no query in flight) for longer than this many milliseconds. A value of zero, the default, disables it.
Defaults and ranges on this page were read from pg_settings on live PostgreSQL 18.4.
What this means
An open transaction that just sits there (BEGIN ran, but the app wandered off without a COMMIT or ROLLBACK) is quietly expensive: it keeps holding locks and pins an old snapshot that stops vacuum from cleaning up dead rows. This setting is the safety net, if a session stays idle inside a transaction longer than the limit, Postgres ends the connection for it. It counts only genuine idle time between statements, not a query that is actually running. Zero, the default, means it never fires, which is fine right up until one forgotten transaction bloats a table.
When it matters
Set as a safety net so an application bug or a paused debugger can't leave a transaction open, and its locks and old snapshot, indefinitely.
| Default | 0 ms |
|---|---|
| Range | 0 – 2147483647 |
| Category | Client connection |
SHOW idle_in_transaction_session_timeout;Tradeoffs
- • Too low: a legitimate pause between statements in the same transaction (waiting on an interactive client, a slow app-side step) gets the whole connection terminated with SQLSTATE 25P03.
- • Disabled (the default): a forgotten open transaction can sit idle forever, holding locks and an old MVCC snapshot that blocks vacuum from cleaning up dead rows.
- • The idle-in-transaction-session-timeout (25P03) lab on this platform measured this directly: with the default (0, disabled), a transaction idle for 3 seconds survived; with the timeout set to 1 second, the same 3-second idle pause got the connection terminated.
Workload profiles
General OLTP
Set a conservative value (seconds, not milliseconds) as a safety net against forgotten open transactions.
Tested in the 25P03 lab: a busy query (pg_sleep) running inside the transaction does not trigger this timeout, only genuine idle time between statements does.
Interactive / long-lived app sessions
Keep transactions short and commit before waiting on user input or an external call, rather than relying solely on this timeout.
The timeout is a safety net, not a substitute for closing transactions promptly.