Browse the docs

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 #

Run Back up when I am on power, but not later than tomorrow
When
  1. Press ⌃⌥B
Do
  1. Run “Back up” when the Mac is charging
Open in Switchboard to try it
Save 5 seconds after the last edit (debounce)
Do
  1. Run “Save draft” at 5s (key save)
Open in Switchboard to try it

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 #

ParameterTypeRequiredValuesWhat it does
macrotextYesRequired. The macro's name or id, or self.
atany valueWhen, as above.
expiresany valueHow long the run may wait: 30m, 1d, or seconds. Without it the run waits until it can start or you cancel it.
holdnumberSeconds the condition must hold before the run starts. Default 2.
ifExistsone ofreplace keep addreplace, keep or add, when a run with the key is already waiting.
ifLateone ofrun skip askrun, skip or ask.
inputsrecordAn object of inputs for the run.
intotextA variable that receives the pending id.
keytextA name for the run, kept per macro.
lateGraceany valueHow late it may start and still simply run. Default 5m.
wakeyes / noKeep the Mac awake for it during its last 10 minutes.
warnany valueHow long before the time to show a heads-up.
whenconditionA 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 when is 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