Run a macro later
Parks a run of a macro until a time ("tomorrow 9", "in 20m") or until a condition becomes true, and returns at once; it survives restarts, runs at most once, and says when it ran late.
Run macro later at at
Examples #
- Press ⌃⌥B
- Run “Back up” when the Mac is charging
- Run “Save draft” at 5s (key save)
Details #
Creates a pending run and carries on. The engine starts the macro with the inputs you gave at at, or as soon as when has been true for hold seconds, whichever happens first. If neither has happened by expires, the run is dropped and logged as expired. macro may be self, this macro, which is how a macro repeats itself on its own schedule.
Pending runs are kept on disk, so they survive a restart. They show in Activity under Waiting, with Cancel and Run now, and in switchboard pending.
If when is already true, the macro starts after the hold. A time less than a second away runs at once.
The step leaves pendingId, and the id also goes into into if you name one. Its output says kept: true when a key kept the run already waiting, and replaced when it replaced one.
Times #
at reads times the way people type them, always meaning the next one: a wait (30s, 20m, 2h, 1h30m, in 20 min), a time of day (21:30, 9pm, noon, midnight, at 9; at 9 on a 12-hour Mac is 9 AM if that is still ahead, else 9 PM; a bare 9 is 9 seconds, so write at 9 or 9am), a day (today 5pm, tonight, tomorrow 9, fri 5:30pm, next monday, this weekend, the 14th; a day alone means 9 AM), a date (Nov 14 at 3pm, 2026-11-14T15:00:00Z) or a bare number, which is seconds from now. A time that has already passed today, like today 8am at noon, fails the step rather than quietly meaning tomorrow.
Keys: replace, keep, add #
Give the run a key and scheduling it again doesn't make a second one. With If one is waiting (ifExists) set to replace (the default with a key), the new run replaces the waiting one, which is how you debounce: "save 5 s after the last edit" pushes the save back on every edit. keep leaves the waiting one and parks nothing, which throttles: "remind me in 20 min" pressed three times is one reminder. add parks another anyway. A key belongs to the macro that scheduled it. Cancel a scheduled run cancels by key, and scheduled(key) reads the waiting one.
Late runs #
A run fires once, never twice, on wall-clock time across sleep and clock changes. If the Mac was asleep or Switchboard wasn't running at the time, the run is late when it gets the chance. Up to lateGrace late (5 minutes by default) it simply runs. Past that it follows ifLate: run (the default) runs it and notes how late and why ("ran 2 h 10 min late: the Mac was asleep"), skip ends it as skipped with the same note, and ask waits for you in Activity until about four times the grace has passed. A run that comes due while the Mac is locked waits for the unlock like any held run, and its lateness still counts from its time.
wake keeps the Mac from idling to sleep during the run's last 10 minutes. macOS doesn't let an app wake a sleeping Mac by itself, so put the Mac to sleep after the run, or keep it awake, if it must not miss it.
In the run it starts #
{{trigger.scheduledFor}} is when it was due (an ISO date), {{trigger.lateBy}} how many seconds late it started (0 on time), {{trigger.source}} who scheduled it ("from Morning", "from ⌥Space"), and {{trigger.key}} its key.
Parameters #
| Parameter | Type | Required | Values | What it does |
|---|---|---|---|---|
macro | text | Yes | Required. The macro's name or id, or self. | |
at | any value | When, as above. | ||
expires | any value | How long the run may wait: 30m, 1d, or seconds. Without it the run waits until it can start or you cancel it. | ||
hold | number | Seconds the condition must hold before the run starts. Default 2. | ||
ifExists | one of | replace keep add | replace, keep or add, when a run with the key is already waiting. | |
ifLate | one of | run skip ask | run, skip or ask. | |
inputs | record | An object of inputs for the run. | ||
into | text | A variable that receives the pending id. | ||
key | text | A name for the run, kept per macro. | ||
lateGrace | any value | How late it may start and still simply run. Default 5m. | ||
wake | yes / no | Keep the Mac awake for it during its last 10 minutes. | ||
warn | any value | How long before the time to show a heads-up. | ||
when | condition | A condition, written as in Only if. |
Every step also accepts label, onFailure, timeout and dryRunSafe.
Gotchas #
Dry run. Nothing is parked; the step says so.
The macro runs as if started by its own trigger: its Only if is skipped when it runs by hand, as always.
Text in
whenis rendered when the step runs, not when the condition is read.AI conditions cannot be watched.
No more than 200 runs of one macro, and 2,000 in all, may wait at once; past that the step fails with the count. A key that replaces never adds to it.
See also #
Cancel a scheduled run, Later, scheduled(), Wait until a condition holds, Run macro, A condition becomes true, Triggers that watch: becomes true, States, waiting runs