Skip to content

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.

Published 6 min read

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.
apple-oss-distributions/xnuiokit/Driverspmgr lives in the closed-source IOKit drivers tree on Apple Silicon.View on GitHub(line )

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:

  1. Scheduler decides which cluster a thread runs on (P vs E).
  2. Cluster's recent utilization is measured.
  3. pmgr picks a P-state based on utilization + thermal headroom + power budget.
  4. 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:

  1. Tells pmgr the cluster is idle.
  2. 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.

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.

Related

What runs in the first microseconds of a Mac boot — the SoC's Boot ROM, the Apple-signed LLB and iBoot stages, the SEP coming up alongside, and how the chain of trust starts.
The Apple SoC isn't just CPU + GPU + SEP. AOP, ANE, ISP, AMC, AMX — half a dozen secondary processors that quietly handle sensors, ML, imaging, and accelerated workloads.
How macOS's GPU driver hands off work to Apple Silicon's tile-based deferred renderer, and why unified memory makes IOSurface zero-copy across CPU and GPU.