![[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`)