cheat sheet

pmset

Inspect and configure sleep, wake, hibernate, and battery behaviour on macOS. Covers per-source profiles, scheduled wake, sleep-prevention diagnostics, battery reports, and hibernate modes.

pmset — macOS Power Management

What it is

pmset is Apple's command-line front end to the macOS Power Management subsystem. It reads and writes the persistent power policy stored in /Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist and com.apple.AutoWake.plist, queries the live state of batteries, assertions, and scheduled wake events, and generates diagnostic data about why the machine slept or woke. Reach for pmset whenever you need a setting that survives reboots, applies per power source (AC vs battery vs UPS), or has to be applied unattended in a deployment script. For a temporary "stay awake right now" hold the lighter caffeinate tool is the right choice; pmset is the durable counterpart.

pmset lives in /usr/bin/pmset and has been part of macOS since 10.4. Most write operations require sudo; the inspection sub-commands run as any user.

Install

pmset ships with macOS — there is nothing to install. Confirm availability.

bash
which pmset
pmset -h 2>&1 | head -5

Output:

text
/usr/bin/pmset
Usage: pmset [-bcuaUB] action [argument]
   or: pmset -g [argument]
…

Syntax

pmset has two main shapes: -g (and its sub-commands) to inspect state, and pmset [scope] action argument to mutate it. Scope flags select which power-source profile is being modified.

bash
pmset -g [SUBCOMMAND]              # query
pmset [SCOPE] SETTING VALUE...     # write
pmset schedule|repeat EVENT ...    # wake/sleep/power schedules

Output: (none — exits 0 on success)

Scope flagApplies to
-aAll profiles (AC + battery + UPS) — the most common writer scope
-cAC (charger / wall power)
-bBattery
-uUPS
-UUPS-specific threshold settings
-BBattery-specific threshold settings

Essential sub-commands

CommandPurpose
pmset -gPrint all current settings for the active power source
pmset -g customPrint persistent settings for every profile (AC, battery, UPS)
pmset -g battBattery state (percentage, AC/battery, charging)
pmset -g schedList scheduled wake/sleep/power events
pmset -g logSleep/wake event log
pmset -g pslogPower-source change log (streamed)
pmset -g assertionsLive power assertions (who is preventing sleep)
pmset -g assertionslogStreamed assertion lifecycle log
pmset -g rawlogRaw kernel power events
pmset -g capHardware power capabilities of this machine
pmset -g thermThermal pressure (battery / CPU / GPU)
pmset -g systemstateOne-shot dump of all power state
pmset schedule EVENT DATETIMESchedule a single power event
pmset repeat EVENT WEEKDAYS TIMERepeating power schedule
pmset sleepnowSleep immediately
pmset displaysleepnowTurn the display off immediately

Inspecting the current policy (pmset -g)

pmset -g with no arguments shows the live setting for every parameter on the currently active power source. Each line is a setting name, a numeric value (minutes for timers, 0 for "never", 1/0 for booleans), and an optional annotation noting whether something is preventing it.

bash
pmset -g

Output:

text
System-wide power settings:
Currently in use:
 standbydelaylow      10800
 standby              1
 halfdim              1
 hibernatefile        /var/vm/sleepimage
 proximitywake        1
 autorestart          0
 disksleep            10
 standbydelayhigh     86400
 sleep                1 (sleep prevented by coreaudiod)
 hibernatemode        3
 highstandbythreshold 50
 displaysleep         2
 tcpkeepalive         1
 ttyskeepawake        1
 darkwakes            1
 gpuswitch            2
 womp                 0
 networkoversleep     0
 powernap             0

To see all three profiles at once (AC, battery, UPS), use -g custom.

bash
pmset -g custom

Output:

text
Battery Power:
 standbydelaylow      10800
 standby              1
 halfdim              1
 sleep                10
 disksleep            10
 displaysleep         2
 hibernatemode        3
 …

AC Power:
 standbydelaylow      10800
 standby              1
 halfdim              1
 sleep                30
 disksleep            10
 displaysleep         10
 hibernatemode        0
 powernap             1
 womp                 1
 …

Setting values

Use one of the scope flags to choose where the change applies, then a setting name and value.

bash
# Display sleeps after 5 min on any power source
sudo pmset -a displaysleep 5

# But: never disk-sleep when on AC; 10 min on battery
sudo pmset -c disksleep 0
sudo pmset -b disksleep 10

# System sleep after 20 min on AC, never on UPS
sudo pmset -c sleep 20
sudo pmset -u sleep 0

Output: (none — exits 0; re-query with pmset -g custom to confirm)

A setting written without sudo returns Insufficient privileges. Write the same value to the same scope multiple times — it is a no-op the second time and does not appear in pmset -g log.

Every persistent setting

The full catalogue is long; below is every commonly-used setting and what it does. The "Profile" column shows which scope (-a/-c/-b) the setting honours.

SettingTypeProfileMeaning
displaysleepminutesa/c/bDisplay sleep timer (0 = never)
disksleepminutesa/c/bSpin-down timer for spinning disks
sleepminutesa/c/bSystem sleep timer (0 = never)
womp0/1a/cWake On Magic Packet (Wake-on-LAN)
ring0/1a/cWake on modem ring (legacy)
autorestart0/1a/c/bAuto-restart after power failure
powerbutton0/1a/cPower button sleeps vs. powers off
lidwake0/1a/c/bWake on lid open (laptops only)
acwake0/1a/c/bWake on AC change (plug/unplug)
lessbright0/1a/c/bSlightly dim display on battery
halfdim0/1a/c/bDim display before full sleep
sms0/1a/c/bSudden Motion Sensor (legacy HDD)
hibernatemodeinta/c/b0 = sleep only, 3 = safe sleep, 25 = hibernate only
hibernatefilepatha/c/bLocation of sleepimage
standbydelayhighsecondsa/c/bTime before standby when battery > threshold
standbydelaylowsecondsa/c/bTime before standby when battery ≤ threshold
highstandbythresholdpercenta/c/bBattery % above which highdelay applies
standby0/1a/c/bWhether standby is allowed
powernap0/1a/cAllow Power Nap (background Mail/Time Machine while asleep)
darkwakes0/1a/cAllow Dark Wake (silent maintenance wakes)
tcpkeepalive0/1a/c/bMaintain TCP connections during Power Nap
ttyskeepawake0/1a/c/bPrevent sleep if a tty session has activity
proximitywake0/1a/c/bWake on Continuity proximity
gpuswitch0/1/2a/c/bDiscrete GPU policy (Intel only)
networkoversleep0/1a/c/bMaintain network access during sleep
destroyfvkeyonstandby0/1a/c/bDiscard FileVault key on standby (T2/Apple Silicon)
autorestartatconnect0/1a (single setting)Auto-power-on when AC is connected. New GUI in Tahoe 26.5; honoured on Mac mini (2024+), Mac Studio (2025+), iMac (2024+).

Reading battery state (-g batt)

pmset -g batt is the canonical battery query — designed-for-script output, deterministic format, one line per battery (always one on Macs that have one).

bash
pmset -g batt

Output:

text
Now drawing from 'AC Power'
 -InternalBattery-0 (id=12345678)	100%; charged; 0:00 remaining present: true
bash
# On battery:
pmset -g batt

Output:

text
Now drawing from 'Battery Power'
 -InternalBattery-0 (id=12345678)	82%; discharging; 4:11 remaining present: true

Parse it with awk for a single-number readout.

bash
pmset -g batt | grep -Eo "\d+%" | head -1

Output:

text
82%

A more structured view comes from ioreg against the AppleSmartBattery class — useful when you need design capacity, full charge capacity, and cycle count separately.

bash
ioreg -rn AppleSmartBattery | grep -E '"(CycleCount|DesignCapacity|MaxCapacity|CurrentCapacity)"' | sort -u

Output:

text
    "CurrentCapacity" = 4521
    "CycleCount" = 247
    "DesignCapacity" = 5183
    "MaxCapacity" = 4980

A handy battery-wear one-liner.

bash
ioreg -rn AppleSmartBattery | awk -F= '
  /"DesignCapacity"/ { d=$2 }
  /"MaxCapacity"/    { m=$2 }
  END { printf "Wear: %.1f%%\n", (1 - m/d) * 100 }'

Output:

text
Wear: 3.9%

Reading the sleep/wake log (-g log)

pmset -g log is a structured, append-only log of every sleep, wake, dark-wake, and assertion event. It is the first place to look when diagnosing "why did my Mac wake at 3 am?" or "the lid is closed but the fan is on".

bash
pmset -g log | tail -20

Output:

text
2026-05-25 02:14:11 -0700 Sleep                Entering Sleep state due to 'Software Sleep pid=153 LidClosed': Using AC (Charge:100%)   1 secs
2026-05-25 06:14:00 -0700 Wake                 DarkWake from Normal Sleep [CDNVA] : due to RTC/EC.WakeTimer/Maintenance Using Batt (Charge:100%)  3 secs
2026-05-25 06:14:03 -0700 DarkWake             due to RTC/EC.WakeTimer/Maintenance
2026-05-25 06:14:33 -0700 Sleep                Entering Sleep state due to 'Maintenance Sleep': Using Batt (Charge:100%)
2026-05-25 07:31:01 -0700 Wake                 Wake from Normal Sleep [CDNVA] : due to LID-OPEN/PowerButton Using AC (Charge:100%)

The annotation in single quotes is the most useful column — it tells you who requested the state change. Common values: LidClosed, LidOpen, Software Sleep (/System/Library/CoreServices/loginwindow.app etc.), Display Sleep Timer, Idle Sleep, Maintenance Sleep, Lid Open, Power Button, User Active.

bash
# Just the wake reasons, last 24 hours
pmset -g log | awk '/Wake .*due to/ {print $1, $2, $0}' | tail -10

Output:

text
2026-05-25 06:14:00 -0700 Wake                 DarkWake from Normal Sleep due to RTC/EC.WakeTimer/Maintenance
2026-05-25 07:31:01 -0700 Wake                 Wake from Normal Sleep due to LID-OPEN/PowerButton

Power assertions (-g assertions)

A power assertion is a runtime promise — typically held by a process or driver — that the system should not enter some sleep state. caffeinate, video players, screen sharers, and active SSH sessions all post assertions. pmset -g assertions lists every one currently held.

bash
pmset -g assertions

Output:

text
2026-05-25 09:14:02 -0700
Assertion status system-wide:
   PreventUserIdleDisplaySleep    1
   PreventUserIdleSystemSleep     1
   PreventSystemSleep             0
   ExternalMedia                  0
   …

Listed by owning process:
   pid 41203(caffeinate): [0x0000000000018b41] 00:00:42 PreventUserIdleSystemSleep named: "caffeinate"
   pid 41203(caffeinate): [0x0000000000018b42] 00:00:42 PreventUserIdleDisplaySleep named: "caffeinate"
   pid 12018(VLC):        [0x0000000000018a51] 02:14:08 PreventUserIdleDisplaySleep named: "VLC is playing"

Each assertion has a 64-bit ID, a duration, a type, and a name. Audit "who is keeping my Mac awake" with a single grep.

bash
pmset -g assertions | grep -E "Prevent(SystemSleep|UserIdle)"

Output:

text
   PreventUserIdleDisplaySleep    1
   PreventUserIdleSystemSleep     1
   PreventSystemSleep             0

The streamed sibling, pmset -g assertionslog, prints a line on every create/release.

bash
sudo pmset -g assertionslog 2>&1 | head -10

Output:

text
2026-05-25 09:31:00 +/- PreventUserIdleSystemSleep   pid 71204 caffeinate
2026-05-25 09:32:01 +/- PreventUserIdleSystemSleep   pid 71204 caffeinate (released)

See the caffeinate cheatsheet for the assertion-creation side of the same story.

Scheduled wake / sleep / restart (schedule and repeat)

macOS supports both one-off and repeating scheduled power events at the firmware level — they fire even when the machine is asleep. There are two commands: pmset schedule for single events, pmset repeat for daily / weekly recurrences.

Single event

bash
# Wake the machine once at 6 am tomorrow
sudo pmset schedule wake "$(date -v+1d -v6H -v0M -v0S '+%m/%d/%y %H:%M:%S')"

# Or with a literal date — note MM/DD/YY HH:MM:SS format
sudo pmset schedule wake "05/26/26 06:00:00"
sudo pmset schedule poweron "05/27/26 08:30:00"
sudo pmset schedule sleep "05/26/26 22:00:00"
sudo pmset schedule shutdown "05/26/26 23:00:00"

Output: (none — exits 0)

The supported event types: wake, poweron, wakeorpoweron, sleep, shutdown, restart.

Repeating schedule

bash
# Wake every weekday at 06:00, sleep every night at 22:30
sudo pmset repeat wakeorpoweron MTWRF 06:00:00 sleep MTWRFSU 22:30:00

Output: (none — exits 0)

MTWRFSU are the day-of-week flags (Monday Tuesday Wednesday tHursday Friday Saturday sUnday). pmset repeat cancel clears any repeating schedule.

Inspecting the schedule

bash
pmset -g sched

Output:

text
Repeating power events:
  wakeorpoweron at 6:00AM weekdays only
  sleep at 10:30PM every day

Scheduled power events:
  [0]  wake at 05/26/2026 06:00:00 by 'com.apple.alarm.user'

To cancel a single scheduled event, identify its index from -g sched and use pmset schedule cancel.

bash
sudo pmset schedule cancel wake "05/26/26 06:00:00"

Output: (none — exits 0)

Hibernate modes

The hibernatemode setting controls how RAM is preserved across sleep. Most modern Macs default to safe sleep (mode 3): RAM remains powered and a copy is written to sleepimage, allowing instant wake on battery and survival of a battery-fail event.

ModeNameRAM poweredsleepimage writtenWake speedBattery use
0Sleep onlyyesnoinstantcontinuous low-draw
3Safe sleep (default)yesyesinstantcontinuous low-draw + one-time write at sleep
25Hibernate onlynoyesslow (10–30 s)none after sleepimage written
bash
# Check current mode
pmset -g | grep hibernatemode

Output:

text
 hibernatemode        3
bash
# Switch to "hibernate only" on battery (long-flight Macbook trick)
sudo pmset -b hibernatemode 25

# Reclaim disk space — sleepimage equals RAM size (24 GB on a 24 GB Mac)
sudo rm -f /var/vm/sleepimage
sudo pmset -a hibernatemode 0   # disable sleepimage altogether

Output: (none — exits 0)

The standby* settings interact with hibernation on Apple Silicon. standbydelayhigh and standbydelaylow decide how many seconds after sleep the machine transitions into deep standby (effectively hibernate); highstandbythreshold is the battery % above which the high delay applies.

bash
# Aggressive deep-standby: enter standby after only 30 minutes when battery <50%
sudo pmset -b standbydelaylow 1800
sudo pmset -b highstandbythreshold 50
sudo pmset -b standbydelayhigh 10800

Output: (none — exits 0)

Sleep diagnostics: g log, assertions, darkwake

The trio for "why isn't this machine sleeping" or "why did it wake".

bash
# 1. What's preventing sleep right now
pmset -g assertions | head

# 2. The actual sleep/wake transitions, last 50 events
pmset -g log | tail -50

# 3. Power-source switches (helpful on UPS or unstable AC)
pmset -g pslog

Output: (varies — see earlier sections)

For deeper investigation, the unified log subsystem com.apple.iokit.power carries kernel-level reasons.

bash
log show --last 1h --predicate 'subsystem == "com.apple.iokit.power"' --info | head -30

Output:

text
2026-05-25 02:14:11 -0700 0x12d   Default   0x0   0   kernel: AppleSPMI: sleep type=Sleep, source=LID
2026-05-25 02:14:11 -0700 0x12e   Default   0x0   0   kernel: AppleARMPMU: entering S3
…

Sleep study (-g sleepstudy)

On Apple Silicon Macs with Modern Standby (S0 Low Power Idle), pmset exposes a sleep-study report similar in spirit to Windows powercfg /sleepstudy. It aggregates Dark Wake duration, battery draw during each session, and the dominant cause of each wake.

bash
sudo pmset -g sleepstudy

Output:

text
Sleep/Wakes log:
Sleep   2026-05-25 02:14:11  Battery (Charge: 100%)
Wake    2026-05-25 06:14:00  DarkWake (Battery 100% -> 99.7%) due to RTC/EC.WakeTimer/Maintenance
        DarkWake duration: 33 s
        Active processes: backupd, mds_stores, sharingd
…

Use this to attribute overnight battery drain to specific maintenance subsystems.

Battery report (-g rawbatt / --show)

For a structured snapshot of the smart-battery state, prefer ioreg; for a tail-of-history view, pmset -g rawbatt (undocumented but widely used) prints adapter and battery details in raw IOReport form.

bash
sudo pmset -g rawbatt 2>&1 | head -20

Output:

text
"AdapterDetails" = {"FamilyCode"=0xe000400c,"AdapterVoltage"=20000,"Watts"=96,"Description"="usb-c","Manufacturer"="Apple Inc."}
"AppleRawCurrentCapacity" = 4521
"AppleRawMaxCapacity" = 4980
"DesignCapacity" = 5183
"CycleCount" = 247
"Temperature" = 305
…

Plot battery health over time by sampling that on a cron and storing it.

bash
ts=$(date +%Y-%m-%dT%H:%M:%S)
ioreg -rn AppleSmartBattery |
    awk -v ts="$ts" -F= '
        /"DesignCapacity"/ { d=$2 }
        /"MaxCapacity"/    { m=$2 }
        /"CycleCount"/     { c=$2 }
        END { printf "%s,%d,%d,%d\n", ts, d, m, c }' \
    >> ~/battery-history.csv

Output: (appends a CSV row; e.g. 2026-05-25T09:14:00,5183,4980,247)

Resetting to defaults

pmset -a overwrites the active profile, but does not restore Apple defaults. To revert to factory power settings, use restoredefaults.

bash
sudo pmset -a restoredefaults

Output: (none — exits 0; pmset -g custom will show factory values)

macOS Tahoe 26 — new settings and undocumented assertion controls

Tahoe 26 introduced two changes worth knowing. First, the new autorestartatconnect setting (also surfaced in System Settings → Energy as "Start up automatically when power is restored") controls whether a desktop Mac powers on the moment an AC adapter is plugged in. Second, Apple's powerd now creates an InternalPreventSleep assertion labelled com.apple.powermanagement.acwakelinger with a ~45-second timeout on every wake — designed so that a brief Push-notification wake stays alive long enough to finish background tasks. On some configurations that linger interferes with prompt return-to-sleep after lid open/close. Two undocumented sub-commands, disableassertion and enableassertion, give scripted control over that.

bash
# New setting — start up automatically when AC is reconnected
# (Mac mini 2024+, Mac Studio 2025+, iMac 2024+)
sudo pmset autorestartatconnect 1
pmset -g | grep autorestartatconnect

# Disable the post-wake "linger" assertion so the Mac returns to sleep promptly
sudo pmset disableassertion InternalPreventSleep

# Re-enable
sudo pmset enableassertion InternalPreventSleep

Output:

text
 autorestartatconnect 1

disableassertion and enableassertion are not documented in man pmset; they accept assertion type names (InternalPreventSleep, PreventUserIdleSystemSleep, PreventUserIdleDisplaySleep, PreventSystemSleep). Disabling InternalPreventSleep is the most common use; disabling user-idle assertions globally would defeat the purpose of caffeinate and similar tools.

The Tahoe 26 sleep/wake stack also picked up a number of compatibility regressions — closing the lid sometimes leads to a "screen will not wake" state, especially on M-series Pro/Max laptops. The pmset -a disablesleep 1 / pmset -a disablesleep 0 toggle pair (also undocumented) is a common temporary mitigation while Apple ships per-model fixes; 26.4.1 resolved a related Wi-Fi-on-wake issue on M5 hardware.

Common pitfalls

  1. Forgetting sudo. Every write subcommand requires root. Unprivileged invocations exit 1 with Insufficient privileges. Scripts must either run as root or use sudo pmset … per line.
  2. Confusing -a, -c, -b, -u. -a is all profiles (most common); -c is AC only; -b is battery only; -u is UPS only. A setting written to -c does not affect battery and vice versa — always re-check with pmset -g custom.
  3. pmset -g shows only the active profile. Reading pmset -g | grep sleep on AC gives the AC value; the same command on battery gives a different number. For full configuration, always use -g custom.
  4. Sleep prevented by an assertion is invisible in pmset -g. The line will read sleep 30 (sleep prevented by audio) — the parenthetical is easy to miss. Always pair with pmset -g assertions when debugging.
  5. powernap is independent of sleep. With sleep 0 the machine never goes to maintenance sleep, but with sleep 30 powernap 1 it sleeps and also wakes silently every hour or so for sync. To get a truly quiet machine, pmset -a powernap 0 darkwakes 0 tcpkeepalive 0.
  6. schedule wake is clock-time, not duration. The format is MM/DD/YY HH:MM:SS in 24-hour local time. Using date arithmetic is the safest way to compute it.
  7. pmset repeat overwrites; it does not append. A second pmset repeat ... invocation replaces the prior schedule. Use one command with both wake and sleep clauses to get both.
  8. Apple Silicon ignores some legacy keys. gpuswitch, sms, lessbright, and ring no longer do anything on Apple Silicon Macs. They are accepted silently for backward compatibility.
  9. hibernatemode 25 plus a small APFS volume = trouble. Hibernation writes sleepimage equal to installed RAM — 64 GB on an M-series Pro. Make sure /var/vm has free space before switching.
  10. Removing /var/vm/sleepimage doesn't change the mode. macOS will recreate it on the next sleep if hibernatemode is non-zero. Set hibernatemode 0 before deleting if you want to reclaim space permanently.
  11. Battery report tools differ. pmset -g batt gives a one-liner. ioreg -rn AppleSmartBattery gives full structured data. system_profiler SPPowerDataType gives human-readable history. Pick the right one for the job.
  12. tcpkeepalive keeps your IP advertised even in sleep. Helpful for "wake on demand" via the cloud, but on a corporate network it can keep TCP sessions alive longer than intended. Set to 0 in deployments where this is undesirable.
  13. womp only works on Ethernet. Wake-on-LAN over Wi-Fi (called Wake-on-Wireless or Bonjour Sleep Proxy) is a separate, harder feature requiring a sleep-proxy Apple device on the LAN.
  14. pmset -g log truncates. On heavily used systems the log rolls and old entries disappear; archive periodically if you need long-term retention.

Real-world recipes

Server-style "never sleep" profile

For a desktop Mac mini used as a build server, headless 24/7.

bash
sudo pmset -c sleep 0 disksleep 0 displaysleep 0 \
    womp 1 autorestart 1 powernap 0 darkwakes 0
sudo pmset -g | grep -E "sleep|womp|autorestart|powernap"

Output:

text
 sleep                0
 disksleep            0
 displaysleep         0
 womp                 1
 autorestart          1
 powernap             0

Presentation mode (no sleep, no dim, no notifications)

A temporary preset for demos — restored on reboot because it's only a caffeinate and defaults flip.

bash
# Persistent for the session
sudo pmset -c displaysleep 0 disksleep 0 sleep 0 halfdim 0
# Suppress Do Not Disturb-bypassing alerts
defaults -currentHost write com.apple.notificationcenterui doNotDisturb -bool true
killall NotificationCenter

Output: (none — exits 0; demo machine will not sleep, dim, or notify)

To revert after the demo:

bash
sudo pmset -a restoredefaults
defaults -currentHost write com.apple.notificationcenterui doNotDisturb -bool false
killall NotificationCenter

Output: (none — restored to factory defaults)

Schedule: wake at 06:00 weekdays, sleep at 22:30 nightly

A typical "be ready when I sit down, save energy overnight" profile.

bash
sudo pmset repeat wakeorpoweron MTWRF 06:00:00 sleep MTWRFSU 22:30:00
pmset -g sched

Output:

text
Repeating power events:
  wakeorpoweron at 6:00AM weekdays only
  sleep at 10:30PM every day

Diagnose "the laptop woke itself at 3 am"

bash
pmset -g log | grep -E "Wake|DarkWake" | tail -10
pmset -g sched
pmset -g assertions | grep -i prevent

Output: (excerpt — shows the wake at 03:00 was a maintenance dark-wake)

text
2026-05-25 03:00:00 -0700 DarkWake             due to RTC/EC.WakeTimer/Maintenance
2026-05-25 03:00:33 -0700 Sleep                Entering Sleep state due to 'Maintenance Sleep'

If you want to silence those, disable Power Nap and Dark Wakes on battery.

bash
sudo pmset -b powernap 0 darkwakes 0 tcpkeepalive 0

Output: (none — exits 0)

Battery wear monitor — weekly cron

A small CSV history file makes a long-term battery wear graph trivial.

bash
cat <<'EOF' > /Users/alice/bin/battery-log.sh
#!/bin/bash
set -e
out=/Users/alice/.local/share/battery-history.csv
ts=$(date +%Y-%m-%dT%H:%M:%S)
ioreg -rn AppleSmartBattery |
    awk -v ts="$ts" -F= '
        /"DesignCapacity"/ { d=$2 }
        /"MaxCapacity"/    { m=$2 }
        /"CycleCount"/     { c=$2 }
        END { printf "%s,%d,%d,%d,%.1f\n", ts, d, m, c, (1-m/d)*100 }' \
    >> "$out"
EOF
chmod +x /Users/alice/bin/battery-log.sh

Output: (none — exits 0)

Pair with a launchd StartCalendarInterval (see launchctl) to run weekly.

Force standby quickly when carrying a laptop in a bag

A common worry: a closed lid that isn't really sleeping warms the chassis and drains the battery. Force standby almost immediately.

bash
sudo pmset -b standbydelaylow 30 standbydelayhigh 30 highstandbythreshold 100

Output: (none — exits 0)

Now the machine drops into deep standby 30 seconds after the lid closes, regardless of battery level.

Audit who is preventing sleep over time

Append snapshots to a log to correlate with user complaints.

bash
out=/Users/alice/.local/share/assertions.log
{
  echo "--- $(date -Iseconds) ---"
  pmset -g assertions
} >> "$out"

Output: (none — appends a timestamped block to assertions.log)

Wake-on-LAN for a build server

Pair pmset -c womp 1 on the server with wakeonlan from another machine.

bash
# On the server
sudo pmset -c womp 1
networksetup -listallhardwareports | grep -A2 Ethernet

Output:

text
Hardware Port: Ethernet
Device: en1
Ethernet Address: a8:66:7f:1b:3e:02
bash
# On the client (with `brew install wakeonlan`)
wakeonlan -i 192.168.1.255 a8:66:7f:1b:3e:02

Output: (none — sends magic packet; server boots within ~30 s)

Recover disk space by killing hibernation

A 64 GB Apple Silicon Mac with a 256 GB SSD can reclaim 64 GB by removing sleepimage.

bash
sudo pmset -a hibernatemode 0
sudo rm -f /var/vm/sleepimage
sudo pmset -a standby 0          # also disable deep-standby write
df -h /System/Volumes/VM

Output:

text
Filesystem        Size   Used  Avail Capacity  iused      ifree %iused  Mounted on
/dev/disk3s1     228Gi   1Mi   164Gi     1%       1   2147483646    0%  /System/Volumes/VM

Investigate sudden battery drain overnight

bash
pmset -g log | awk '/Dark|Sleep|Wake/ && $1 > "2026-05-24" && $1 < "2026-05-25"'
pmset -g assertions | grep "Prevent"
sudo log show --predicate 'subsystem == "com.apple.iokit.power"' \
    --info --start "2026-05-24 22:00:00" --end "2026-05-25 08:00:00" | tail -30

Output: (composite — shows wake events, ongoing assertions, and kernel power transitions; typical culprits are Mail IMAP IDLE, Time Machine, or a third-party VPN keeping tcpkeepalive alive)

Reset everything to Apple defaults

After heavy experimentation, restore factory power policy in one command.

bash
sudo pmset -a restoredefaults
pmset -g custom | head -40

Output:

text
Battery Power:
 standbydelaylow      10800
 standby              1
 …
AC Power:
 standbydelaylow      10800
 standby              1
 …

Headless Mac mini auto-restart after power failure

Useful for a Mac mini stashed in a network closet that absolutely must come back if the power blips.

bash
sudo pmset -c autorestart 1
sudo pmset -c sleep 0 disksleep 0 displaysleep 5
sudo pmset -c womp 1

Output: (none — exits 0)

After the next power cycle, the Mac mini will boot, sit on the login screen with the display sleeping after 5 minutes, and remain accessible over Ethernet via WoL or simple SSH.

Sources

PMSET Command — power management settings in macOS (ss64.com) Using pmset to set autorestartatconnect on macOS Tahoe 26.5.0 — Der Flounder pmset disableassertion InternalPreventSleep / acwakelinger — GitHub gist What's new for enterprise in macOS Tahoe 26 — Apple Support Apple Silicon deep sleep state not responding — MacRumors Forums

  • caffeinate — temporary, process-bound "stay awake" assertion. Use for one-off jobs; use pmset only for persistent policy.
  • tmutil — Time Machine; commonly affected by the powernap and sleep settings, which decide when scheduled backups actually run.
  • launchctl — to drive scheduled scripts that use pmset (e.g. battery-wear logger). See macos-cli for the basic launchd walkthrough.
  • ioreg -rn AppleSmartBattery — raw structured battery data; ideal pair for scripted health monitoring.
  • system_profiler SPPowerDataType — human-readable battery history including charge cycle count and condition string.
  • log show --predicate 'subsystem == "com.apple.iokit.power"' — kernel power events; the truthful answer when pmset -g log is too high-level.