# PostgreSQL Wait Event Atlas

> What the backend is waiting for, where the wait begins, and what an operator should do next.
---

<div class="wait-deck">
  <div class="wait-panel">
    <div class="wait-panel__eyebrow">Operator entry point</div>
    <h2>Start with the waiting sessions, not the event name</h2>
    <p>Capture who is waiting, how long, whether a transaction is open, and who blocks it. Then use the event page to connect the snapshot to PostgreSQL source and a bounded response.</p>
  </div>
  <div class="wait-stats" aria-label="Catalogue coverage">
    <div class="wait-stat"><strong>13–18</strong><span>PostgreSQL versions</span></div>
    <div class="wait-stat"><strong>327</strong><span>versioned matrix identities</span></div>
    <div class="wait-stat"><strong>8</strong><span>operator-facing classes</span></div>
    <div class="wait-stat"><strong>2</strong><span>languages, paired page-for-page</span></div>
  </div>
</div>

<div class="signal-strip"><span class="signal-dot"></span><strong>Fact chain</strong><code>official docs → pg_wait_events → source grep → executable SQL</code></div>

## Take the first snapshot {#first-snapshot}

Run this before restarting anything or cancelling a backend:

```sql {title="Waiting sessions right now"}
SELECT pid, backend_type, usename, datname, application_name,
       state, now() - query_start AS query_age,
       now() - xact_start AS xact_age,
       wait_event_type, wait_event,
       pg_blocking_pids(pid) AS blocking_pids,
       left(query, 160) AS query
FROM pg_stat_activity
WHERE wait_event IS NOT NULL
ORDER BY query_age DESC NULLS LAST;
```

> [!IMPORTANT]
> A wait-event snapshot shows **where a process is sleeping now**, not what consumed the elapsed query time. Repeat the snapshot and correlate it with latency, throughput, locks, and operating-system evidence before calling a wait the cause.

Continue with the [wait-event triage map](/triage/) or open the class that matches `wait_event_type`.

## Read by class {#classes}

| Class | Read it as | First question |
| --- | --- | --- |
| [Lock](/lock/) | Another transaction or session owns a heavyweight lock | Who is at the head of the blocking chain? |
| [LWLock](/lwlock/) | Internal shared-memory structure is contended | Is one internal resource hot across repeated samples? |
| [IO](/io/) | A backend is waiting for a file operation | Is storage slow, or is PostgreSQL simply doing expected work? |
| [IPC](/ipc/) | Processes are coordinating with each other | Which peer or phase has not reached the rendezvous? |
| [Client](/client/) | PostgreSQL is waiting on the application or network | Is the session idle, backpressured, or inside a transaction? |
| [Activity](/activity/) | A background process is in its normal main loop | Is this expected idleness for that backend type? |
| [Timeout](/timeout/) | A deliberate timer or rate limit has not expired | Which policy intentionally inserted the delay? |
| [BufferPin](/bufferpin/) | A buffer cannot move while another backend pins it | Which cursor or scan is holding the pin? |

The generic [extension wait-event mechanism](/extension/) is documented separately; extension-defined names are intentionally outside this catalogue.

## Evidence contract {#evidence-contract}

Every finished event page carries four different kinds of statement:

1. **Fact** — identity, version presence, and official description.
2. **Analysis** — the source path that reports the wait and what that path is doing.
3. **Advice** — a workload-aware normal/trouble boundary and scenario-specific action.
4. **Evidence** — executable SQL plus source `file:line`, tied to an exact PostgreSQL release.

Use the [version matrix](/matrix/) when an event appears on one major version but not another.

---

Section pages:

- [Wait-event triage map](/triage/): A decision tree from one pg_stat_activity snapshot to the next safe action.
- [Version matrix](/matrix/): The reconciled PostgreSQL 13–18 wait-event inventory, including renames and type moves.
- [Operator glossary](/glossary/): Terms used consistently across identity, analysis, advice, and evidence fields.
- [Lock waits](/lock/): Heavyweight locks whose owner and blocking chain can usually be identified from SQL.
- [LWLock waits](/lwlock/): Contention on PostgreSQL's internal shared-memory data structures.
- [I/O waits](/io/): File reads, writes, synchronization, allocation, and asynchronous I/O completion.
- [IPC waits](/ipc/): PostgreSQL processes waiting for peers, workers, barriers, queues, or phase changes.
- [Client waits](/client/): PostgreSQL waiting for an application, network socket, TLS/GSS handshake, or replication client.
- [Activity waits](/activity/): Background processes sleeping in their main loop until work arrives.
- [Timeout waits](/timeout/): Deliberate sleeps, retry intervals, throttles, and rate-limiting delays.
- [BufferPin waits](/bufferpin/): A backend needs an exclusive buffer pin while another backend still holds one.
- [Extension wait events](/extension/): How PostgreSQL extensions register and report custom wait-event names, and why they are outside the core catalogue.
- [Related GUCs](/guc/): Configuration controls referenced by wait-event response guidance.
- [Related metrics](/metric/): Signals used to decide whether a wait is expected or harmful.
