cheat sheet
caffeinate
Prevent display, idle, system, or user-active sleep for the duration of a command, a fixed time, or a process — without permanently changing pmset.
caffeinate — Keep macOS Awake on Demand
What it is
caffeinate is a small Apple-shipped command-line utility that posts a power assertion against the macOS power-management subsystem to prevent some or all forms of sleep for the duration of an invocation. It is the scripted equivalent of nudging the trackpad every minute: cleaner, faster, and tied to a process lifetime so it can never be left running after its parent dies. Reach for caffeinate whenever you need a one-off "don't sleep right now" promise — a long backup, an overnight build, a recording session, a presentation — without modifying the persistent pmset settings that survive across reboots. If you need a permanent policy (always wake at 06:00, never sleep on AC), use pmset instead.
caffeinate lives in /usr/bin/caffeinate and is part of every macOS install from Mountain Lion (10.8) onward; no Homebrew package or third-party app is required.
Install
caffeinate is preinstalled on macOS. Verify the binary path and version.
which caffeinate
caffeinate -h 2>&1 | head -5
Output:
/usr/bin/caffeinate
usage: caffeinate [-disu] [-t timeout] [-w pid] [command [arguments]]
There is no Linux or Windows port; the closest analogues are systemd-inhibit on Linux and powercfg /requestsoverride on Windows.
Syntax
caffeinate accepts zero or more mode flags, an optional timeout, an optional PID to track, and an optional command to run. With no arguments and no command it runs until killed with Ctrl-C; with a command it inherits the command's lifetime.
caffeinate [-disu] [-t SECONDS] [-w PID] [COMMAND [ARGS...]]
Output: (none — exits 0 on success)
Essential flags
| Flag | Meaning |
|---|---|
-d | Prevent display sleep (screen stays on) |
-i | Prevent idle sleep (system stays awake even if idle) |
-s | Prevent system sleep while the machine is on AC power |
-u | Declare user activity — wakes display for ~5 s, then exits |
-m | Prevent disk sleep |
-t SECONDS | Run the assertion for at most this many seconds, then exit |
-w PID | Hold the assertion until the given process exits |
| (no flag) | Default behaviour ≈ -d — display assertion only |
The mode flags are additive — caffeinate -dis posts three assertions at once.
The four assertion types
macOS exposes a small set of named power assertions. caffeinate is a thin wrapper that maps each command-line flag to one of these assertions; they are the same assertions you see in pmset -g assertions.
| Flag | Underlying assertion | What it prevents |
|---|---|---|
-d | PreventUserIdleDisplaySleep | Display dimming / sleeping |
-i | PreventUserIdleSystemSleep | System sleep when idle (display may still sleep) |
-s | PreventSystemSleep | System sleep on AC; ignored on battery |
-u | UserIsActive | Briefly wakes display (≈5 s) — does not hold awake |
Inspect the current set of assertions on a running system.
pmset -g assertions
Output:
2026-05-25 09:14:02 -0700
Assertion status system-wide:
BackgroundTask 0
ApplePushServiceTask 0
UserIsActive 0
PreventUserIdleDisplaySleep 1
PreventSystemSleep 0
PreventUserIdleSystemSleep 1
ExternalMedia 0
PreventDiskIdle 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"
The 64-bit hex blob is the assertion ID; the duration is HH:MM:SS; the named string shows the holder.
Running until Ctrl-C
The simplest invocation: no command, no timeout. Posts the default display assertion and blocks until you press Ctrl-C.
caffeinate
Output: (none — blocks the terminal; the display will not sleep until you interrupt)
caffeinate -di # also prevent idle system sleep
caffeinate -dim # plus prevent disk idle
Output: (none — blocks until interrupted)
Use this when you're stepping away from the machine for a moment but want to come back to a still-active screen, or when a foreground task in another tab needs the system kept up.
Running for a fixed time (-t)
-t SECONDS is the cleanest pattern for "keep this machine awake for exactly N seconds, then let it sleep again". The assertion is released the instant the timer fires — no Ctrl-C needed.
caffeinate -i -t 3600 # 1 hour of "no system sleep"
caffeinate -dis -t 1800 # 30 min: no display, no idle, no system sleep
caffeinate -di -t $((8*3600)) # 8 hours overnight
Output: (none — exits 0 once the timer elapses)
A common shell idiom for awake-for-N-hours.
hours=4
caffeinate -di -t $((hours*3600))
echo "Caffeinate window closed at $(date)"
Output:
Caffeinate window closed at Sun May 25 13:14:02 PDT 2026
Wrapping a command
The most useful mode: pass a command after the flags and caffeinate will run that command, hold the assertion for exactly its lifetime, and exit with the command's exit code. This is automatic, safe, and impossible to leak — when the wrapped command dies, the assertion releases.
caffeinate -i make build
caffeinate -dis ./long-test.sh
caffeinate -i rsync -aH /Users/alice/src/ /Volumes/Backup/src/
caffeinate -dis ffmpeg -i in.mov -c:v libx265 -crf 22 out.mp4
Output: (whatever the wrapped command emits — caffeinate adds nothing of its own)
Quote arguments carefully — everything after the first non-option token is passed to the inner command.
# Wrong — `2` is interpreted as an extra argument to `caffeinate`, not to `sleep`
caffeinate -i sleep 2
# Right — works because flag parsing stops at `sleep`
caffeinate -i sleep 2
# When in doubt, separate with --
caffeinate -i -- sleep 2
Output: (none — exits 0 after 2 seconds)
Both forms above happen to work, but the -- separator is safer if your inner command starts with a dash.
Attaching to an existing PID (-w)
-w PID holds the assertion until the named process exits, then releases. This is the right pattern when the workload was started by something else — a GUI app, a launchd job, another shell session — and you don't want to restart it under caffeinate.
# Find the PID of a running Final Cut export
pgrep -f "Final Cut Pro" | head -1
# Keep the system awake until that PID dies
caffeinate -dis -w 7821
Output: (none — blocks until PID 7821 exits, then exits 0)
A real-world combo: start the long task in the background, capture its PID, then attach.
./overnight-render.sh > render.log 2>&1 &
render_pid=$!
caffeinate -i -w "$render_pid"
echo "render PID $render_pid finished with status $?"
Output:
render PID 7821 finished with status 0
Multiple -w flags can be passed; caffeinate exits only when all of the tracked PIDs have exited.
caffeinate -i -w 7821 -w 7842 -w 7901
Output: (none — exits 0 when the last of those three PIDs ends)
Declaring user activity (-u)
-u is not a long-hold flag; it tells the OS "the user just did something" which wakes the display for roughly five seconds and then exits. Use it to nudge the screen on from a script (status notification, alarm) without holding any persistent assertion.
caffeinate -u -t 5 # wake the display for 5 seconds, then exit
Output: (none — display turns on; caffeinate exits after 5s)
-u has no effect on a desktop without an attached display, and on a laptop with the lid closed the wake is suppressed.
Display sleep vs system sleep vs idle sleep
The flags overlap in confusing ways. The mental model: macOS has three sleep states the user can hit, plus one tier above that for "is the user even here".
| Flag | Keeps display on? | Keeps CPU running? | Keeps disk spinning? | On AC only? |
|---|---|---|---|---|
-d | yes | no — system can still idle-sleep | no | no |
-i | no (display can dim/sleep) | yes | no | no |
-s | no | yes | no | yes |
-m | no | no | yes | no |
-d -i | yes | yes | no | no |
-d -i -m | yes | yes | yes | no |
-d -i -s | yes | yes | no | yes |
Choose by use case:
- Watching a long video / kiosk display →
-d - Headless build, server task, scp/rsync →
-i - Recording or live transcoding that must not pause →
-i -s - Backup writing many files to a slow USB drive →
-i -m
Laptop lid behavior
Closing a MacBook lid on AC power normally triggers clamshell mode (sleep if no external display attached). caffeinate cannot fully override this — even with -dis, closing the lid with no external display will sleep the machine. Apple deliberately gated this in the kernel so a closed laptop in a bag does not overheat.
Workarounds, ordered from least to most invasive.
- Plug in an external display, keyboard, or mouse — clamshell with peripherals stays awake automatically.
- Use
pmset -b -c -u sleep 0andpmset -a disksleep 0to disable sleep persistently (thencaffeinate -iis unneeded — seepmset). - Install a kernel-extension-free tool like
Amphetamine(App Store) which works around the clamshell restriction via assertions on macOS where Apple still allows it. - Reset via
sudo pmset -a disablesleep 1(System Integrity Protection must be off on older macOS).
The clean rule: caffeinate works fine until you close the lid; if you need lid-closed-awake, you need external peripherals or Amphetamine.
Battery vs AC behavior
caffeinate -s is a no-op while the machine is on battery: by design, macOS will not honour PreventSystemSleep to protect battery life. The other three flags (-d, -i, -u) work on both AC and battery.
# On battery this is equivalent to caffeinate -di (the -s is silently ignored)
caffeinate -dis -t 3600
Output: (none — runs for an hour; on battery the -s half of the assertion never fires)
If you genuinely need "stay awake while unplugged", caffeinate -di is the maximum you can ask of macOS without changing persistent settings via pmset -b sleep 0.
Logging and verifying assertions
Combine with pmset -g assertions and the log stream to verify your invocation is doing what you expect.
caffeinate -dis -t 60 &
sleep 1
pmset -g assertions | head -20
Output:
[1] 71204
2026-05-25 09:30:18 -0700
Assertion status system-wide:
BackgroundTask 0
ApplePushServiceTask 0
UserIsActive 0
PreventUserIdleDisplaySleep 1
PreventSystemSleep 1
PreventUserIdleSystemSleep 1
ExternalMedia 0
PreventDiskIdle 0
To see assertion lifecycle events live, tail the unified log.
log stream --predicate 'subsystem == "com.apple.iokit.power"' --info --debug \
--style compact | grep -i assertion
Output:
2026-05-25 09:30:19 powerd: PMAssertion: pid=71204 caffeinate: created PreventUserIdleSystemSleep
2026-05-25 09:31:19 powerd: PMAssertion: pid=71204 caffeinate: released
Verbose-style alternative — pmset assertion CLI
pmset -g assertionslog provides a one-shot, second-by-second log suitable for piping into a file when you need a forensic record of who held what.
sudo pmset -g assertionslog | head -30
Output:
2026-05-25 09:31:00 +/- PreventUserIdleSystemSleep pid 71204 caffeinate
2026-05-25 09:32:01 +/- PreventUserIdleSystemSleep pid 71204 caffeinate (released)
This is the right tool when investigating "why didn't my Mac sleep last night?" — see the pmset cheatsheet for the full assertion / sleep-log walkthrough.
Common pitfalls
- Default behaviour is display-only.
caffeinatealone (no flags) keeps the display on but does not prevent system sleep on idle. Add-iif the task is CPU-bound and the screen can dim. The most common "it slept anyway" report is this missing flag. -sis silently ignored on battery. Don't rely oncaffeinate -sfor an unplugged laptop; use-iinstead and accept that AC-only system sleep cannot be deferred from userland.- Closing the lid sleeps the machine regardless. No
caffeinateflag prevents clamshell-without-peripherals sleep. Plug in external input or display, or changepmsetpolicy permanently. - Forgetting to wrap with
--for commands that start with a dash.caffeinate -i --some-toolinterprets--some-toolas a flag tocaffeinate. Usecaffeinate -i -- --some-toolto disambiguate. - Background
caffeinate &without await. When wrapped in a script that exits, the backgroundedcaffeinateis reparented to launchd and keeps running. Alwayswaitfor it, or use-t SECONDS, or use-w $$to tie its lifetime to the parent script's PID. - Holding too many assertions for too long. Each minute of
-ion battery costs real charge —caffeinateitself is free, but the workload it protects burns through battery. Pair with-tto bound the cost. - Expecting
-uto hold the screen on.-usimulates user activity for ~5 s then exits. It is not a "keep on" flag; use-dfor that. - Running inside
tmux/screenand detaching. The assertion persists as long as thecaffeinateprocess is alive, but if you kill the inner shell from another terminal the assertion is released. Verify withpmset -g assertions. - macOS Power Nap can still wake the machine. Even with
caffeinate -srunning, Power Nap may schedule periodic wakes for Time Machine, Mail, and iCloud sync. Disable withpmset -a powernap 0if a perfectly quiet machine is required. - CPU thermal throttling overrides everything. If the chassis hits its thermal envelope during a long render, macOS will throttle and may doze briefly to recover.
caffeinatecannot override hardware-level thermal management.
Real-world recipes
Overnight rsync to an external drive
A common use case: nightly mirror of ~/Code to an attached USB-C drive. You want the machine awake, disks spinning, but the screen can sleep.
caffeinate -i -m -t $((10*3600)) \
rsync -aH --info=progress2 \
/Users/alice/Code/ /Volumes/Backup/Code/
Output:
148,234,591,002 84% 76.32MB/s 0:08:11 (xfr#9412, ir-chk=183/124003)
If the rsync finishes early the timer is irrelevant — caffeinate exits with rsync's status the moment rsync returns.
Long ffmpeg encode with the screen off
Save battery and prevent screen burn-in while a multi-hour h.265 encode runs.
caffeinate -i ffmpeg -hwaccel videotoolbox -i in.mov \
-c:v hevc_videotoolbox -b:v 8M out.mp4
Output:
frame= 4612 fps= 38 q=-0.0 size= 14336kB time=00:01:17.12 bitrate=1523.4kbits/s
…
Attach to a Time Machine backup PID
Find the running backupd and prevent system sleep until it finishes.
pid=$(pgrep -x backupd)
[ -n "$pid" ] && caffeinate -i -w "$pid" && echo "Time Machine backup complete."
Output:
Time Machine backup complete.
See the tmutil cheatsheet for the full backup-orchestration story.
Wake-on-status-change script
Wake the display to flash a notification when a build fails.
make build || { caffeinate -u -t 5; \
osascript -e 'display notification "Build failed!" with title "make"'; }
Output: (display lights up for ~5s and a notification banner appears)
Run-until-this-shell-exits guard
If you want every command in an interactive shell session to keep the machine awake, drop this into ~/.zprofile.
# Keep system awake while this login shell exists
caffeinate -i -w $$ &
disown
Output: (none — every new login shell gets paired with a caffeinate -i that dies when the shell ends)
Presentation mode
For demos and presentations: no sleep, no display dim, no Power Nap, for two hours.
caffeinate -dis -t $((2*3600)) &
echo "Presentation mode active for 2 hours (caffeinate PID $!)."
Output:
Presentation mode active for 2 hours (caffeinate PID 71455).
To cancel early, kill 71455.
Race against the system sleep timer
Useful in pmset/caffeinate troubleshooting — schedule a wake, then caffeinate to deliberately not sleep before that wake to confirm the wake fires.
sudo pmset schedule wake "$(date -v+10M '+%m/%d/%y %H:%M:%S')"
caffeinate -di -t 600
pmset -g sched
Output:
Repeating power events:
wake at 05/25/2026 14:14:00
Scheduled power events:
[0] wake at 05/25/2026 14:14:00 by 'com.apple.alarm.user'
Bound a Docker build
docker build of a large image set can run 30+ minutes; bound the system-awake window to twice that.
caffeinate -i -t 3600 -- docker compose build --pull
Output:
[+] Building 1432.7s (78/78) FINISHED
Sanity-check from another terminal
Confirm a long-running caffeinate is actually still posting its assertions.
ps -o pid,command -p "$(pgrep -x caffeinate | head -1)"
pmset -g assertions | grep caffeinate
Output:
PID COMMAND
71204 caffeinate -dis -t 7200
pid 71204(caffeinate): [0x0000000000018b41] 00:42:11 PreventUserIdleSystemSleep named: "caffeinate"
Conditional caffeinate based on power source
Only post the assertion when on AC — let battery sessions sleep normally.
if pmset -g batt | grep -q "AC Power"; then
caffeinate -i -t 3600 ./long-task.sh
else
./long-task.sh
fi
Output: (depends on power state — runs the task either way; assertion held only on AC)
Sources
References consulted while writing this article. Links open in a new tab.
- Apple Developer — caffeinate(1) man page — Authoritative flag list used while writing the options reference.
- SS64 — caffeinate — Cross-version notes.
Related tools
pmset— persistent power policy (sleep timers, schedules, hibernate mode). Use when you need the setting to outlive the current invocation.tmutil— Time Machine backup orchestration; commonly wrapped incaffeinate -i -w $(pgrep -x backupd).macos-cli— broader macOS terminal reference; contains the original short note oncaffeinatethat this article expands.pmset -g assertions— read the live assertion table to see whether (and which)caffeinatecalls are currently active.