![[res_cpu.png|256]] CPU is consumed by query execution, background maintenance
processes, and spinlock contention. Unlike [[Disk IO]] or [[Network]], CPU waits
in Postgres wait events appear as [[Activity]] (background processes
idle-looping) or [[Timeout]] (`SpinDelay`).
- **Tuning**:
[19.4.6 Worker Processes](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-WORKER-PROCESSES),
[19.4.3 Kernel Resource Usage](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-KERNEL)
- **Visibility**: [[Activity]] wait events, [[Timeout]] (`SpinDelay`), query
execution time
## Key Concepts
## Parallel Workers
- **Description**: Postgres can spawn background worker processes to parallelize
scans, joins, and aggregations. Controlled by
`max_parallel_workers_per_gather`
- **Impact**: `ExecuteGather`, `ParallelFinish` IPC waits; `ParallelQueryDSA`
LWLock waits
## Background Workers
- **Description**: Autovacuum workers, WAL sender/receiver, logical replication
workers, and checkpointer are persistent background processes competing for
CPU
- **Impact**: [[Activity]] wait events show when these processes are
idle-looping; CPU saturation shows as elevated query latency
## Spinlocks
- **Description**: Busy-wait locks used for very short critical sections
(microseconds). If a spinlock can't be acquired immediately, the backend spins
in a tight loop
- **Impact**: `SpinDelay` Timeout wait; under high concurrency this can consume
significant CPU
## Cost-based Vacuum Delay
- **Description**: AUTOVACUUM deliberately sleeps between I/O operations to
avoid saturating CPU and I/O on busy systems
- **Impact**: `VacuumDelay` Timeout wait
## Key Config Parameters
| Parameter | Default | Purpose |
| ---------------------------------- | ------- | ------------------------------------------- |
| `max_worker_processes` | 8 | Total background worker slots |
| `max_parallel_workers` | 8 | Max workers for parallel query |
| `max_parallel_workers_per_gather` | 2 | Workers per parallel query node |
| `max_parallel_maintenance_workers` | 2 | Workers for parallel VACUUM/CREATE INDEX |
| `autovacuum_max_workers` | 3 | Max simultaneous autovacuum processes |
| `vacuum_cost_delay` | 2 ms | Sleep between vacuum I/O bursts |
| `vacuum_cost_limit` | 200 | I/O cost budget before vacuum sleeps |
| `cpu_tuple_cost` | 0.01 | Planner cost estimate per tuple processed |
| `cpu_index_tuple_cost` | 0.005 | Planner cost estimate per index entry |
| `cpu_operator_cost` | 0.0025 | Planner cost estimate per operator/function |
## Related Workloads
- [[Activity]] — background process CPU loops
- [[Timeout]] (`SpinDelay`, `VacuumDelay`)
- [[IPC]] (`ExecuteGather`, `ParallelFinish`, `BgWorkerStartup`)