Source: Anthropic official docs — Scheduled tasks Type: Product Feature Product: Claude Code Requires: Claude Code v2.1.72 or later

Session-scoped scheduling for Claude Code: re-run a prompt automatically on an interval (poll a deploy, babysit a PR, watch a build), or set a one-time reminder. Tasks live inside the current conversation and stop when you start a new one. Unlike Routines (cloud, durable) or Desktop scheduled tasks (machine-resident, durable), /loop is the lightweight option for inside an open session.

Three scheduling options compared

Cloud RoutinesDesktop scheduled tasks/loop (this article)
Runs onAnthropic cloudYour machineYour machine
Requires machine onNoYesYes
Requires open sessionNoNoYes
Persistent across restartsYesYesRestored on --resume if unexpired
Local file accessNoYesYes
MCP serversPer-taskConfig files + connectorsInherits from session
Permission promptsNone (autonomous)ConfigurableInherits from session
Customizable scheduleVia /scheduleYesYes
Minimum interval1 hour1 minute1 minute

/loop usage

Alias: /proactive is an alias for /loop as of Week 16 (v2.1.105). Both forms work identically.

FormExampleBehavior
Interval + prompt/loop 5m check the deployRuns on a fixed cron schedule
Prompt only/loop check the deployClaude picks an interval (1m–1h) per iteration
Interval only / nothing/loop or /loop 15mRuns the built-in maintenance prompt or loop.md

You can also pass another slash command as the prompt: /loop 20m /review-pr 1234.

Fixed interval

Supplied intervals can lead (30m do X) or trail (do X every 2 hours) the prompt. Units: s, m, h, d. Seconds round up to the nearest minute (cron has 1-minute granularity). Intervals like 7m or 90m are rounded to the nearest clean cron step and Claude tells you what was picked.

Claude-paced (dynamic) interval

When you omit the interval, Claude chooses one between 1 minute and 1 hour after each iteration based on what it observed: short waits while a build is finishing, longer when nothing is pending. The chosen delay and reasoning print at the end of each iteration. Claude may use the Monitor tool (built-in since v2.1.98, Week 15) for these — a background watcher that streams events into the conversation as new transcript messages, often more token-efficient than re-running prompts. With Monitor, /loop check CI on my PR can stop polling entirely and just react to events as they happen.

Bedrock / Vertex AI / Microsoft Foundry: prompt with no interval runs on a fixed 10-minute schedule instead.

Built-in maintenance prompt

Bare /loop runs Claude through, in order:

  • continue any unfinished work from the conversation,
  • tend to the current branch’s PR (review comments, failed CI, merge conflicts),
  • run cleanup passes (bug hunts, simplification) when nothing else is pending.

Irreversible actions (push, delete) only proceed when they continue something the transcript already authorized.

Bedrock / Vertex AI / Microsoft Foundry: /loop with no prompt prints usage instead of running the maintenance loop.

loop.md (custom default)

Replace the built-in maintenance prompt with your own. Two locations, first match wins:

PathScope
.claude/loop.mdProject-level. Takes precedence when both files exist.
~/.claude/loop.mdUser-level. Applies in any project that does not define its own.

Plain Markdown — write it like you’d type a /loop prompt directly. Edits take effect on the next iteration. Truncated past 25,000 bytes.

Stopping a loop

Press Esc while it’s waiting for the next iteration. This clears the pending wakeup. Tasks scheduled by asking Claude directly (not via /loop) are not affected by Esc — delete them with the cron tools.

One-time reminders

Describe in natural language; Claude schedules a single-fire task that deletes itself after running.

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

Manage scheduled tasks

Ask Claude in natural language (“what scheduled tasks do I have?”, “cancel the deploy check”), or reference the underlying tools:

ToolPurpose
CronCreateSchedule a task. Takes a 5-field cron expression, the prompt, and recurring vs one-shot.
CronListList all scheduled tasks with IDs, schedules, and prompts.
CronDeleteCancel a task by 8-character ID.

A session can hold up to 50 scheduled tasks at once.

Cron expression reference

5-field standard: minute hour day-of-month month day-of-week. Wildcards (*), single values (5), steps (*/15), ranges (1-5), comma lists (1,15,30).

ExampleMeaning
*/5 * * * *Every 5 minutes
0 * * * *Every hour on the hour
0 9 * * *Every day at 9am local
0 9 * * 1-5Weekdays at 9am local
30 14 15 3 *March 15 at 2:30pm local

Day-of-week: 0 or 7 is Sunday, 6 is Saturday. Not supported: extended syntax like L, W, ?, name aliases (MON, JAN). When both day-of-month and day-of-week are constrained, a date matches if either matches (vixie-cron semantics).

All times interpreted in local timezone0 9 * * * is 9am wherever you’re running Claude Code, not UTC.

How tasks run

The scheduler checks every second for due tasks and enqueues them at low priority. A scheduled prompt fires between turns, not mid-response. If Claude is busy when a task comes due, the prompt waits until the current turn ends.

Jitter

To stop every session hitting the API at the same wall-clock moment:

  • Recurring tasks fire up to 30 minutes after the scheduled time (or up to half the interval, for tasks that run more often than hourly). An hourly job scheduled for :00 may fire anywhere up to :30. (Prior to W19, this was “up to 10% of period, capped at 15 minutes”.)
  • One-shot tasks scheduled for the top or bottom of the hour fire up to 90 seconds early.

The offset is derived from the task ID, so the same task always gets the same offset. Pick a non-:00/:30 minute (e.g., 3 9 * * *) to skip one-shot jitter entirely.

Seven-day expiry

Recurring tasks automatically expire 7 days after creation. They fire one final time, then delete themselves. To last longer, cancel and recreate before expiry — or use Routines / Desktop scheduled tasks for durable scheduling.

Disable scheduled tasks

Set CLAUDE_CODE_DISABLE_CRON=1 in your environment. The cron tools and /loop become unavailable; already-scheduled tasks stop firing.

Limitations

  • Tasks only fire while Claude Code is running and idle.
  • No catch-up for missed fires — busy through a scheduled time means it fires once when Claude becomes idle, not once per missed interval.
  • Starting a fresh conversation clears all session-scoped tasks. claude --resume / --continue restores unexpired tasks (recurring within 7 days of creation, one-shots whose time hasn’t passed). Background Bash and Monitor tasks are never restored on resume.

Key Takeaways

  • /loop is the lightweight, session-scoped scheduler — for cloud durability use Routines; for machine durability, Desktop scheduled tasks.
  • Three usage shapes: fixed interval (/loop 5m ...), Claude-paced (/loop ... with no interval), or bare /loop for the built-in maintenance prompt or your loop.md.
  • Recurring loops auto-expire after 7 days; reset by recreating, or pick a durable scheduler upstream.
  • Jitter is deterministic (derived from task ID) — predictable per task, scattered across sessions in aggregate.
  • Esc cancels a pending /loop wakeup. Cron tasks scheduled directly need CronDelete by ID.
  • Available since Claude Code v2.1.72. To turn off: CLAUDE_CODE_DISABLE_CRON=1.

Try It

  1. Smoke test: in any session, run /loop 1m print the time. Watch it fire once, cancel with Esc.
  2. PR babysitter: create .claude/loop.md in a project with: “Check the release/next PR. If CI red, pull the failing job log and propose a fix. If review comments arrived, address each. If green and quiet, say so in one line.” Then run bare /loop in that project.
  3. Self-paced poll: /loop check whether CI passed and address any review comments — Claude shortens intervals while active, lengthens once quiet.
  4. One-shot reminder: remind me in 45 minutes to check the integration tests.
  5. List with: “what scheduled tasks do I have?” Cancel with: “cancel the deploy check job.”

Open Questions

  • What is the precise “low priority” enqueue behavior — does a long-running tool call extend wait beyond the user’s current turn?
  • Are session-scoped tasks shared across claude --continue from different terminals, or per-tty?
  • Does the Monitor tool’s streaming output count toward the 50-task session limit?