Power management on Apple Silicon: pmgr, DVFS, and idle clusters
How macOS keeps an Apple Silicon Mac running for 18 hours on a battery — cluster-level voltage scaling, idle gating, the pmgr driver, and the power-island architecture.
An M-series MacBook can deliver hours of work on a battery that would barely run an Intel laptop for two. The CPU performance is competitive with desktops while the chip draws single-digit watts when idle. The technology underneath that gap is Dynamic Voltage and Frequency Scaling (DVFS) plus aggressive idle clustering, all orchestrated by a driver called pmgr.
This article walks the power management story on Apple Silicon.
Power islands — the SoC's coarse-grained units
The Apple SoC is partitioned into power islands — chunks of silicon that can be independently power-gated. Major islands:
- P-cluster (performance cores).
- E-cluster (efficiency cores).
- GPU (one big island, sometimes subdivided per core block).
- ANE (Neural Engine).
- ISP (Image Signal Processor).
- Media engines (ProRes, HEVC, etc.).
- AOP (Always-On Processor — stays on continuously).
- Display engine.
- SEP (Secure Enclave — its own power management).
Each island has its own power rail, its own clock domain, its own enable/disable control register. Power management at the OS level is the orchestration of which islands are powered, at what voltage, at what frequency, at what moment.
The pmgr driver
pmgr (power manager) is the IOKit driver that owns the SoC's power-control registers. It's the kernel-side single source of truth for "what's powered, at what voltage, running at what frequency."
What pmgr does:
- DVFS control — per-cluster voltage + frequency selection. Higher P-state = more performance + more power; lower P-state = less of both.
- Idle gating — when all cores in a cluster idle, gate the cluster (drop voltage, stop the clock; eventually power-gate entirely).
- Wake coordination — when a core needs to wake from idle, pmgr restores the cluster state.
- Per-island sequencing — bringing up the GPU is a multi-step sequence (power, then clock, then unreset); doing it wrong corrupts the GPU.
pmgr publishes a power-state interface other IOPM-aware drivers can consume — they tell pmgr "I need full power" or "I'm idle"; pmgr aggregates and chooses the right global state.
DVFS — voltage/frequency scaling per cluster
Each CPU cluster has a table of P-states — operating points combining a voltage and a frequency. A typical M-series chip exposes 15-20 P-states per cluster, ranging from a few hundred MHz at low voltage (idle) to several GHz at peak voltage (sustained turbo).
The scheduler influences P-state selection:
- Scheduler decides which cluster a thread runs on (P vs E).
- Cluster's recent utilization is measured.
- pmgr picks a P-state based on utilization + thermal headroom + power budget.
- The P-state is applied: voltage is set first (must be high enough for the target frequency to be stable), then frequency is bumped.
Frequency changes are fast (microseconds). Voltage changes are slower (tens of microseconds to settle) — voltage is what gates the speed of transition between distant P-states.
The voltage-frequency curve is convex, which is why running two CPUs at half speed is more efficient than one CPU at full speed for parallelizable work. Apple's scheduler exploits this: spreading work across E-cores at moderate frequency often beats concentrating it on a P-core at high frequency for the same throughput.
Idle states — what happens when nothing is running
When all threads on a cluster have blocked (waiting on IPC, blocked on I/O, sleeping), the scheduler runs the cluster's idle thread. The idle thread:
- Tells pmgr the cluster is idle.
- Issues a
wfi(Wait For Interrupt) — a low-power wait instruction.
pmgr can then:
- Light idle: drop the P-state to the lowest level but keep clocks running. Wake latency: ~µs.
- Clock-gated idle: stop the clock. Wake latency: ~10 µs.
- Power-gated idle: drop voltage to zero, power-gate the cluster. Wake latency: ~100 µs to ~1 ms.
The choice is dynamic — pmgr predicts how long the idle will last based on recent activity and picks the deepest state that's likely to amortize its wake cost.
This is why a "doing nothing" Mac draws so little power: the active cluster is in light idle, the unused cluster is power-gated, the GPU is power-gated, most coprocessors are off. The AOP keeps a heartbeat going.
Per-cluster — and per-core where possible
On modern M-series chips, idle gating can happen at the per-core granularity within a cluster — not just the whole cluster. A 4-core P-cluster with one busy core can park the other three independently.
This is more sensitive than it sounds: power-gating an individual core requires saving its architectural state and restoring on wake. The scheduler's "keep threads on the same core for cache warmth" heuristic interacts here — too much migration costs both cache misses and per-core wake overhead.
Thermal management
Layered on DVFS is thermal management. The SoC has temperature sensors throughout; thresholds are configured:
- Normal: full DVFS table available.
- Thermal pressure: P-cluster is capped to a lower P-state.
- Thermal critical: P-cluster is offlined entirely; only E-cluster runs.
- Thermal emergency: the OS is shut down to protect the silicon.
You can observe thermal pressure via:
pmset -g thermlog
This is why a MacBook running heavy workloads on a hot day might suddenly slow down — pmgr is throttling the P-cluster to keep temperatures in safe range.
Battery-aware policy
When on battery, pmgr's policy shifts:
- Lower default P-state ceilings — full peak performance available but only when actually needed.
- More aggressive idle gating — shorter idle horizons trigger deeper states.
- GPU is more aggressively power-gated — even during light GPU activity, the GPU may be cycled on/off rather than kept warm.
- Display brightness lowered by default — the display is a major power consumer.
When on AC, pmgr is more permissive — full performance is available without aggressive battery preservation.
What surprises newcomers
- DVFS happens at the cluster level, not per-core, on most operations. All cores in a cluster share a voltage rail.
- Apple Silicon's power efficiency comes from heterogeneous + DVFS together. Just having P and E cores wouldn't help if both ran at the same voltage; the cluster-level DVFS is what makes E-cores efficient at low load.
- The wake-from-idle latency varies enormously — sub-µs for light idle, ~ms for power-gated. The scheduler avoids deep idle when it expects work soon.
- Thermal throttling is a normal mode, not a fault. A MacBook on your lap doing heavy work will throttle; the alternative is unsafe silicon temperatures.
What to read next
For Apple's user-facing power tools:
pmset -g # current power assertions and policy
pmset -g thermlog # thermal events
powermetrics --samplers cpu_power,gpu_power,ane_power
And the AOP and coprocessors article — the AOP is the always-on counterpart to all the things pmgr powers down.
For the IOPM article — pmgr is a participant in the IOKit power graph, not a separate system.