What pg_stat_activity means
pg_stat_activity is a dynamic view with one row per PostgreSQL server process. For client backends, it can show the database, role, application label, connection and transaction timestamps, current state, and wait event.
It is a current observation, not cumulative history. A session can change state immediately after your query, and PostgreSQL does not fully synchronize every field in the row.
Inspect session groups without query text
This bounded, read-only summary omits the query, client address, and process identifier. It excludes the inspecting session and groups the remaining connections by safe operational dimensions.
SELECT
COALESCE(usename, 'unknown') AS role_name,
COALESCE(NULLIF(application_name, ''), 'unlabeled') AS application_name,
COALESCE(state, 'unknown') AS state,
wait_event_type,
wait_event,
count(*) AS session_count,
min(backend_start) AS oldest_connection_start,
min(xact_start) AS oldest_transaction_start,
min(CASE WHEN state = 'active' THEN query_start END) AS oldest_active_query_start
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid()
GROUP BY usename, application_name, state, wait_event_type, wait_event
ORDER BY session_count DESC, role_name, application_name
LIMIT 50;Interpret state and time columns
| Field | What it means | Interpretation guardrail |
|---|---|---|
state = active | The backend is executing a query. | Active can be doing work or waiting; inspect wait_event separately. |
state = idle | The backend is waiting for a new client command outside a transaction. | Idle pooled connections can be normal and are not automatically a leak. |
state = idle in transaction | A transaction is open but no query is currently executing. | It is a risk signal whose age, locks, and application owner need review—not automatically an incident. |
xact_start | When the current transaction began, or null when no transaction is active. | Transaction age is different from connection age and query age. |
query_start | Start time of the active query, or of the last query when the backend is not active. | Only use it as active-query age when state is active. |
state_change | When the backend last changed state. | It does not describe every earlier transition. |
Read wait events separately from state
state and wait_event are independent. An active backend with a non-null wait event is executing a query but blocked somewhere, while a client wait can simply mean PostgreSQL is waiting for the application to send more work.
Wait-event types identify broad areas such as locks, client communication, I/O, IPC, buffer pins, timeouts, and extension-defined waits. The event supplies evidence about where a backend is paused; it does not identify the root cause by itself.
Safe inspection workflow
- Start with grouped counts and timestamps rather than query text or client addresses.
- Compare connection count with the configured limit and with an understood application baseline.
- Review the oldest active query and transaction ages, then confirm whether scheduled or administrative work explains them.
- For waiting active sessions, inspect the wait type before assuming CPU, storage, or locking is responsible.
- Repeat observations over time before labeling a transient snapshot as sustained pressure.
Common misleading interpretations
- Many idle connections do not necessarily mean PostgreSQL is overloaded; pool design and available connection capacity matter.
- An active session is not necessarily consuming CPU at that moment.
- A wait event is not automatically an error, and a null wait event does not prove healthy execution.
- A long-running query or transaction can be intentional maintenance or reporting work.
- The query field shows the last query for non-active sessions, not a query that is still running.
When DatabaseMeter can help
The PostgreSQL health check returns bounded counts for active, idle, idle-in-transaction, waiting, long-running query, and long-transaction sessions without returning SQL text, process identifiers, or client addresses.
Connected telemetry stores grouped application, role, state, and connection-count observations. That supports comparisons over time while preserving the distinction between a one-time session snapshot and a sustained connection pattern.
Definitions and sources
Provider and PostgreSQL statements last reviewed August 29, 2026. Pricing consoles and invoices remain authoritative.
Related database resources
How to interpret pg_stat_statements
Rank normalized query fingerprints while accounting for cumulative counters, resets, and privacy.
Open resourceWhen PostgreSQL sequential scans matter
Use table counters and query plans to distinguish expected sequential scans from review candidates.
Open resourcePostgreSQL health check
Analyze bounded PostgreSQL catalog statistics locally—without connecting your database.
Open resource