![[res_cpu.png|64]]
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`)