Hello!
I've been successfully using StartCalendarInterval in Launch[Agent|Daemon] *.plists for years.
You know the deal: Mac is sleeping when CalendarInterval passes, then launchd runs the job when Mac is awoken. (This behavior is described at the bottom of an Apple doc from 2016 -- exactly how it worked before!)
Recently, behavior has changed: with the computer asleep, when the date/time of the CalendarInterval passes, macOS runs the job! Even when "sleeping".
However, it gets stranger: macOS will start a job when sleeping, but then suspend it in the middle.
I wrote a timestamped log to check this behavior: I see job start, pause in the middle, then resume hours later when a user wakes the computer.
This all makes me think that "sleep" on macOS in the past few years is now defined differently -- perhaps an Apple Silicon change? But I can't find documentation that covers this. Buried in a WWDC video, maybe?
Has anyone else seen this change in launchctl calendar scheduled jobs?
Well I committed the cardinal sin of not eliminating enough variables before debugging. Time to set the record straight!
Here's what I learned:
- Above, I was wrong: in fact, macOS 26, 15, 12 (and earlier!) all DO exhibit this behavior: running a
CalendarIntervalscheduled job when MacBook is sleeping. - The differentiator is not the OS version but the state of the lid -- lid open while asleep and you get the DarkWake behavior:
launchdruns your job, it may still get suspended until a full wake - Lid closed while asleep - behavior is as described here -- your job does not run in any way until the lid is opened
- I don't know what desktop Macs do here (no lid!).
- There is a
PowerNapboolean key used by Apple in/System/Library/LaunchDaemons/*.plists, but I wasn't able to suss out its behavior, and it only seems to be used in acom.apple.xpc.activitydictionary. If you'd like to give this a go for your own devices, dear reader, I wish you luck.
I was mis-attributing OS version to this launchd behavior, when it was actually that two of my test machines had different lid states. Mea culpa!
The title of this thread, therefore, should read "launchd StartCalendarInterval behavior depends on lid state"
And thanks again, Etresoft.