# Wait-event triage map

> A decision tree from one pg_stat_activity snapshot to the next safe action.
---

The map is deliberately conservative: preserve evidence first, separate expected idleness from stalled work, and only then choose a class-specific drill-down.

```mermaid
flowchart TD
  A[Capture pg_stat_activity] --> B{wait_event is null?}
  B -- yes --> C[The backend is on CPU or between instrumentation points]
  B -- no --> D{Activity or Client?}
  D -- yes --> E{Idle state or expected background loop?}
  E -- yes --> F[Usually normal; check open transactions and connection volume]
  E -- no --> G[Check client backpressure, network, and application ownership]
  D -- no --> H{Lock or BufferPin?}
  H -- yes --> I[Build the blocking chain and identify the root holder]
  H -- no --> J{IO?}
  J -- yes --> K[Correlate with pg_stat_io, filesystem latency, and workload phase]
  J -- no --> L{LWLock?}
  L -- yes --> M[Repeat snapshots; identify one hot internal resource]
  L -- no --> N[Inspect IPC peer or Timeout policy]
  I --> O[Choose the least disruptive bounded action]
  K --> O
  M --> O
  N --> O
```

## Minimum evidence bundle {#bundle}

- Two or more snapshots with timestamps.
- `pid`, `backend_type`, `state`, query age, transaction age, event type and name.
- `pg_blocking_pids(pid)` for every waiting backend.
- The exact PostgreSQL major/minor version.
- A workload marker: deploy, batch, checkpoint, vacuum, backup, DDL, or failover.

> [!WARNING]
> Do not terminate a backend merely because its wait is frequent. `Activity`, many `Client`, and timer waits can dominate a healthy cluster by design.
