Scheduled tasks
Clock-driven repetition inside an open session. The /loop bundled skill
re-runs a prompt on an interval — poll a deploy, babysit a PR, check back on a long build. It feels like cron
because it is cron under the hood — but it runs a model that decides what to do each tick,
not a fixed script.
Analogy β a kitchen timer wired to a cook. The timer rings every
N minutes (the cron part); each time it rings, the cook looks at the current state of the kitchen and decides what to do
next (the decision-maker part). Cron alone just rings a bell and runs the same script; /loop rings the bell
and thinks.
/loop runs a model and only while your session is open and idle. /goal
is the condition-driven cousin (keep going until a check passes), where /loop is clock-driven
(every N minutes). Routines are the cloud/unattended cousin that
survive a closed laptop — /loop does not.Mechanism β what you provide determines the mode
Both the interval and the prompt are optional, and what you give decides the behaviour:
fixed cron
Claude picks the delay
maintenance prompt
/loop 5m check if the deployment finished and tell me what happened # fixed interval /loop check whether CI passed and address review comments # Claude-chosen interval /loop 20m /review-pr 1234 # re-run a saved command each tick remind me at 3pm to push the release branch # a one-shot, scheduled in natural language
The cron tools, jitter & expiry
Under the hood Claude uses CronCreate (5-field cron expression + prompt + recurs/once),
CronList, and CronDelete (by 8-char ID). A session holds up to 50 tasks.
The scheduler checks every second and fires a due prompt between your turns, never mid-response, at low
priority. Jitter adds a deterministic offset (recurring tasks up to 30 min late) so every
session doesn’t hit the API at once.
Tasks are session-scoped: starting a new conversation clears them; --resume/--continue
restores any that haven’t expired. Recurring tasks auto-expire 7 days after creation (one final
fire, then delete) — this bounds how long a forgotten loop can run. Press Esc while a /loop
waits to stop it. Disable the whole scheduler with CLAUDE_CODE_DISABLE_CRON=1.
When to reach for it
/loop or a loop.md.When not to
Best practices
/loop (prompt only) so Claude waits longer when nothing’s pending — cheaper and more responsive than a fixed tick.:00/:30 if exact timing matters — jitter offsets the round ones.