How to see running queries in PostgreSQL

The answer is the pg_stat_activity view. Here is the query to paste, then what the columns actually mean.

SELECT pid,
       usename,
       state,
       now() - query_start AS runtime,
       wait_event_type,
       left(query, 100) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY query_start;

Reading the output

Who is blocking whom

When something shows wait_event_type = 'Lock', find the blocker:

SELECT waiting.pid  AS waiting_pid,  left(waiting.query, 60)  AS waiting_query,
       blocking.pid AS blocking_pid, left(blocking.query, 60) AS blocking_query,
       now() - blocking.xact_start  AS blocking_xact_age
FROM pg_stat_activity waiting
JOIN pg_stat_activity blocking
  ON blocking.pid = ANY (pg_blocking_pids(waiting.pid));

The usual suspects, ready to paste

-- Query attive da più di 5 minuti:
SELECT pid, now() - query_start AS runtime, left(query, 100)
FROM pg_stat_activity
WHERE state = 'active' AND query_start < now() - interval '5 minutes'
ORDER BY query_start;

-- Sessioni "idle in transaction" (tengono lock e bloccano vacuum):
SELECT pid, usename, now() - xact_start AS xact_age, left(query, 100)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;

Permissions: you always see your own sessions in full; other users' query text requires membership in pg_read_all_stats (or superuser). If the query column says <insufficient privilege>, that's why.

🔍 Found the slow query? Run it with EXPLAIN (ANALYZE, BUFFERS) and paste the output into the EXPLAIN Visualizer. Need to stop it instead? See how to kill a query safely.