obsidian/wiki/claude-code/scheduled-tasks.md
2026-04-17 13:09:44 +01:00

6.9 KiB
Raw Blame History

title aliases tags sources created updated
Scheduled Tasks & /loop
loop
cron-tasks
session-scheduling
claude-code
scheduling
cron
loop
automation
raw/Run prompts on a schedule.md
2026-04-17 2026-04-17

Scheduled Tasks & /loop

Run prompts automatically on a repeating interval or fire one-time reminders inside a Claude Code session. Requires v2.1.72+ (claude --version).

Tasks are session-scoped: they live in the current conversation. --resume / --continue restores unexpired tasks; a fresh session clears them.


Scheduling Options Compared

Cloud Routines Desktop Tasks /loop (session)
Runs on Anthropic cloud Your machine Your machine
Machine must be on No Yes Yes
Open session required No No Yes
Persistent across restarts Yes Yes Restored if unexpired
Local file access No (fresh clone) Yes Yes
Min interval 1 hour 1 minute 1 minute
  • Cloud → reliable unattended runs, no local machine needed
  • Desktop → local files + tools, no open session needed
  • /loop → quick in-session polling, simplest to start

/loop — Quick Reference

Command Behavior
/loop 5m check the deploy Fixed cron interval, your prompt
/loop check the deploy Dynamic interval Claude chooses each iteration
/loop Built-in maintenance prompt, dynamic interval
/loop 15m Built-in maintenance prompt, fixed interval
/loop 20m /review-pr 1234 Re-run another skill on a fixed schedule

Fixed Interval

/loop 5m check if the deployment finished
  • Units: s, m, h, d — seconds round up to nearest minute
  • Non-clean steps (7m, 90m) are rounded; Claude tells you what it picked

Dynamic Interval

  • Omit the interval; Claude picks 1 min1 hour based on observed state
  • Short waits when something is active; longer when idle
  • May use the Monitor tool internally (streams background script output — more token-efficient than polling)
  • Jitter rules don't apply; 7-day expiry does

Built-in Maintenance Prompt (bare /loop)

Each iteration, in order:

  1. Continue unfinished work from the conversation
  2. Tend to the current branch's PR (review comments, failed CI, merge conflicts)
  3. Run cleanup passes (bug hunts, simplification) when nothing else is pending

Irreversible actions (push, delete) only proceed if already authorized in the transcript.

Customize with loop.md

Replaces the built-in prompt for bare /loop calls:

Path Scope
.claude/loop.md Project-level (takes precedence)
~/.claude/loop.md User-level fallback
  • Plain Markdown, no required structure
  • Edits take effect on the next iteration — refine while running
  • Max 25,000 bytes (content beyond is truncated)
  • Ignored when you supply a prompt on the command line

One-Time Reminders

Describe in natural language — Claude creates a single-fire task that self-deletes after running:

remind me at 3pm to push the release branch
in 45 minutes, check whether the integration tests passed

Managing Tasks

Natural language works:

what scheduled tasks do I have?
cancel the deploy check job

Underlying tools:

Tool Purpose
CronCreate Schedule a task (5-field cron, prompt, recurring flag)
CronList List tasks with IDs, schedules, prompts
CronDelete Cancel task by ID
  • Each task has an 8-character ID (used with CronDelete)
  • Max 50 scheduled tasks per session

How Tasks Fire

  • Scheduler checks every second; tasks enqueue at low priority
  • Fires between turns — never mid-response
  • If Claude is busy when a task comes due, it waits until the current turn ends
  • All times are local timezone (not UTC)

Jitter

  • Recurring: fires up to 10% of period late, capped at 15 min (e.g. hourly → :00:06)
  • One-shot at :00 or :30: fires up to 90 s early
  • Offset is deterministic from task ID → same task, same offset
  • To avoid jitter: pick a non-:00/:30 minute (e.g. 3 9 * * *)

Seven-Day Expiry

  • Recurring tasks auto-expire 7 days after creation; fire once more then self-delete
  • To extend: cancel and recreate, or switch to Routines / Desktop tasks

Cron Expression Reference

5-field format: minute hour day-of-month month day-of-week

Expression Meaning
*/5 * * * * Every 5 minutes
0 * * * * Every hour on the hour
7 * * * * Every hour at :07
0 9 * * * Daily at 9am local
0 9 * * 1-5 Weekdays at 9am local
30 14 15 3 * March 15 at 2:30pm local
  • 0/7 = Sunday through 6 = Saturday
  • Supports: *, single values, steps (*/15), ranges (1-5), lists (1,15,30)
  • No extended syntax: L, W, ?, name aliases (MON, JAN) not supported
  • If both day-of-month and day-of-week are set, a date matches if either matches (vixie-cron semantics)

Disable Scheduling

CLAUDE_CODE_DISABLE_CRON=1

Disables the scheduler entirely. CronCreate, CronList, CronDelete, and /loop become unavailable; already-scheduled tasks stop firing.


Limitations

  • Tasks only fire while Claude Code is running and idle — closing the terminal stops them
  • No catch-up for missed fires (fires once when Claude goes idle, not per missed interval)
  • Fresh conversation clears all tasks; --resume/--continue restores unexpired ones
  • Background Bash and monitor tasks are never restored on resume
  • On Bedrock / Vertex AI / Microsoft Foundry: dynamic /loop falls back to a fixed 10-min schedule; bare /loop prints usage instead of starting maintenance loop

Key Takeaways

  • /loop is the fastest way to poll during a session — interval optional, prompt optional
  • Omitting the interval gives Claude adaptive waits (short when active, long when idle)
  • Bare /loop runs a built-in PR/CI maintenance loop; loop.md customizes it per project
  • One-time reminders need no special syntax — just describe them in natural language
  • Session tasks expire after 7 days; use wiki/claude-code/overview for durable scheduling
  • The CronCreate / CronList / CronDelete tools are what /loop calls under the hood
  • Disable entirely with CLAUDE_CODE_DISABLE_CRON=1


Sources