Long-Running Transaction
System views: pg_stat_activity
Overview
Long-running transactions hold row-level locks, prevent VACUUM from reclaiming dead tuples behind the transaction's xmin horizon, and accumulate WAL that cannot be recycled until the transaction closes. A single stalled transaction can cause table bloat across every table touched by that transaction—even tables the transaction never wrote to.
insightral flags any transaction open longer than five minutes that is not in the 'idle' state. This covers both active queries and transactions that are holding locks while the application sleeps between statements. The five-minute threshold is conservative; many teams set the alarm at two minutes.
Detection SQL
Run this query with a read-only role. No writes, no locks.
-- Transactions open for more than 5 minutes
SELECT
pid,
usename,
application_name,
client_addr,
state,
wait_event_type,
wait_event,
now() - xact_start AS xact_duration,
now() - query_start AS query_duration,
left(query, 100) AS current_query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
AND now() - xact_start > interval '5 minutes'
AND state <> 'idle'
ORDER BY xact_start;Fix SQL
Replace placeholders in <angle brackets> with values from the detection output before running.
-- Terminate the long-running backend (use with care)
SELECT pg_terminate_backend(<pid>);
-- Or cancel only the current query, leaving the transaction open
SELECT pg_cancel_backend(<pid>);Worked example
A background job opened a transaction to batch-export 50,000 rows, then the application hung waiting for a downstream API. The transaction stayed open for 47 minutes. During that time, autovacuum could not reclaim 1.2M dead tuples from the users table (also written to in the same txn). Table bloat grew from 4% to 19% before the job was killed.
Common false positives
- Intentional long-running maintenance transactions (e.g., large data migrations) — add a pg_stat_activity application_name prefix like 'migration:' and configure insightral's exception list.
- Read-only long transactions (pg_dump, logical replication slots) — these still block VACUUM but are often expected; filter by state = 'idle in transaction'.
Check for long-running transaction across your whole estate.
Insightral runs this rule — and 98 more — continuously inside your private cloud, with read-only credentials and nothing leaving your network.
Request early accessLast updated: 2026-05-13 · View all published rules
