Warning Connections

Idle Transaction

A connection is in "idle in transaction" state, holding locks and preventing VACUUM from cleaning up dead tuples.

What is this issue?

An "idle in transaction" connection has:
1. Started a transaction (explicitly or implicitly)
2. Stopped executing queries
3. Not committed or rolled back

This is dangerous because:
- Transactions hold locks that block other operations
- Old transactions prevent VACUUM from removing dead tuples
- They can lead to table bloat and XID wraparound

Common causes:
- Application bug (forgot to commit/rollback)
- Connection pool not releasing transactions
- User left a psql session open with an uncommitted transaction
- Application crashed mid-transaction

Why it matters

Lock Holding

May hold locks that block other queries or DDL operations

Vacuum Blocking

Prevents VACUUM from cleaning dead tuples, causing bloat

XID Age

Old transactions prevent XID freezing, risking wraparound

Resource Waste

Connection slot occupied without doing useful work

How PG Pilot detects it

```sql
SELECT
  pid,
  usename,
  application_name,
  client_addr,
  state,
  xact_start,
  age(now(), xact_start) AS transaction_age,
  query
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;
```

How to fix it

1

Identify the problem session

Check how long the transaction has been idle:

SELECT pid, usename, application_name,
       age(now(), xact_start) AS tx_age,
       age(now(), state_change) AS idle_time
FROM pg_stat_activity
WHERE state = 'idle in transaction';
2

Investigate the cause

Check what the session was doing before going idle:

SELECT pid, query FROM pg_stat_activity WHERE pid = YOUR_PID;

Also check if it's holding locks:

SELECT * FROM pg_locks WHERE pid = YOUR_PID;
3

Terminate if necessary

If the transaction is abandoned, terminate it:

-- Graceful cancellation
SELECT pg_cancel_backend(YOUR_PID);

-- Force termination if cancel doesn't work
SELECT pg_terminate_backend(YOUR_PID);


4

Set idle transaction timeout

Prevent future issues with automatic termination:

ALTER SYSTEM SET idle_in_transaction_session_timeout = '5min';
SELECT pg_reload_conf();

Prevention

  • Set idle_in_transaction_session_timeout in postgresql.conf
  • Configure connection pools to detect and close abandoned transactions
  • Use statement_timeout for application queries
  • Review application code for proper transaction handling

Related Issues

Related Features

PostgreSQL Documentation