pg_blocking_pids
PG 9.6+→ integer[]Returns an array of PIDs that are blocking the given server process from acquiring a lock. Returns an empty array if the process is not blocked.
Signature
pg_blocking_pids ( pid integer ) → integer[]Parameters
| Parameter | Type | Description |
|---|---|---|
| pid | integer | PID of the process to check for blockers |
Examples
SELECT pid, pg_blocking_pids(pid) AS blocked_by FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0;All currently blocked processes and their blockersSELECT a.pid, a.usename, a.query, a.state, pg_blocking_pids(a.pid) AS blocked_by FROM pg_stat_activity a WHERE cardinality(pg_blocking_pids(a.pid)) > 0;Blocked sessions with their blocking PIDs and query textSELECT count(*) AS blocked_sessions FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0;Number of currently blocked sessionsSELECT pid, usename, query, pg_blocking_pids(pid) AS blocked_by FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0;All blocked sessions — investigate when count is persistently non-zeroCalling pg_blocking_pids on every row in pg_stat_activity in a tight monitoring loop — the function inspects lock structures for each call; querying it for hundreds of connections repeatedly can itself impose overhead; sample at a reasonable interval. Also: Assuming the returned PIDs are the root cause — pg_blocking_pids returns the immediate blocker; that blocker may itself be blocked by another process. Follow the chain recursively or use a CTE to find the root blocker. Also: Using pg_cancel_backend on a pid from pg_blocking_pids without checking if it is idle-in-transaction — cancelling an actively-executing query is safe; cancelling an idle-in-transaction session leaves the transaction open and may not release locks immediately. Also: Treating an empty array return as proof that no blocking exists — advisory locks and certain lock types (e.g., predicate locks) are not covered by pg_blocking_pids; use pg_locks for a complete picture.
✓ Instead: See description and related functions for the correct approach.
`pg_blocking_pids(pid)` always returns an array (possibly empty). Filter with `cardinality(pg_blocking_pids(pid)) > 0` to find only processes that are genuinely blocked, then optionally call `pg_cancel_backend` on the blocking pid.
SELECT pid, usename, query, pg_blocking_pids(pid) AS blocked_by FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid)) > 0;Blocked sessions with which PIDs are blocking them