Loop: Recurring Local Execution
/loop runs a Claude Code command on a recurring schedule on your local machine. Think of it as a cron job that speaks Claude — no cloud account needed, no server required, just your terminal staying open and doing useful work in the background.
Syntax
# Run a command every N minutes/loop [interval] [command]
# Examples/loop 30m "check the PR queue and summarize new reviews"/loop 1h "run the test suite and report failures"/loop 6h "fetch the external pricing API and update prices.json if changed"
# Stop the loop/loop --stop
# List active loops/loop --list
# Stop a specific loop by ID/loop --stop <loop-id>The interval supports m (minutes), h (hours), and d (days). Minimum interval is 5 minutes.
Duration Limit
A single /loop session runs for up to 3 days. After 72 hours, the loop exits cleanly and logs a summary of all runs. To extend beyond 3 days, restart the loop or use /schedule for cloud-based execution that does not depend on your machine staying awake.
How It Works
/loop is purely local. When you start a loop:
- Claude Code registers the command and interval in the session state
- At each interval, Claude Code wakes up and executes the command as a fresh task
- Results are logged to
~/.claude/loops/<loop-id>/runs/ - The loop continues until you stop it, the session ends, or 3 days elapse
Because the loop runs in your terminal session, your machine must stay awake and Claude Code must remain running. If the process is killed, the loop stops. Use /schedule if you need cloud-resilient execution.
Loop lifecycle:
/loop 30m "command" │ ▼ ┌─────────────┐ │ Register │ ← stores interval + command └──────┬──────┘ │ ▼ ┌─────────────┐ wait 30m ┌─────────────┐ │ Execute │ ───────────────► │ Execute │ ← repeats └──────┬──────┘ └─────────────┘ │ ▼ (on /loop --stop or 3d elapsed) ┌─────────────┐ │ Exit + │ │ Summary │ └─────────────┘How to Stop Safely
Stopping a loop mid-run waits for the current execution to finish before exiting. This prevents partial writes or incomplete operations.
# Graceful stop — waits for current run to finish/loop --stop
# Stop a specific loop (when running multiple)/loop --list # get loop IDs/loop --stop loop-abc123 # stop by ID
# Force stop (does not wait for current run)/loop --stop --forceLogs from all completed runs are preserved in ~/.claude/loops/<loop-id>/ even after the loop stops.
/loop vs /schedule
| Feature | /loop | /schedule |
|---|---|---|
| Execution location | Local machine | Cloud (Vercel/Claude.ai) |
| Machine must be on | Yes | No |
| Max duration | 3 days | 1 week |
| Requires account | No | Claude.ai Pro |
| Internet dependency | No (unless task needs it) | Yes |
| Use case | Dev tasks, local monitoring | Long-running, off-hours jobs |
Use /loop when the task needs local file access or you want zero cloud dependency. Use /schedule when the task should run even if your laptop is closed.
Setup / Prerequisites
No special setup required. /loop works with any Claude Code installation.
Recommended: keep a terminal window dedicated to loops so you can monitor output without it interfering with your coding session.
# Recommended: run in a separate terminal pane# (tmux, iTerm2 split pane, Windows Terminal tab)claude /loop 30m "check PR queue"Examples
1. Monitor PR Queue Every 30 Minutes
/loop 30m "check GitHub for new PRs targeting main. For each PR opened in the last 30 minutes, post a summary comment with: files changed, estimated review time, and any obvious issues (missing tests, large diff). Tag me in the comment."Claude checks the PR queue, reads each new pull request, and posts a structured summary comment. You get notified through GitHub’s normal notification system.
2. Run Tests Hourly
/loop 1h "run npm test. If any tests fail, open the relevant source files, identify the likely cause, and create a GitHub issue with the test name, error message, and your hypothesis. Label it 'test-failure'."Useful during long development sessions when you want continuous test monitoring without watching the terminal.
3. Check External API Every 6 Hours
/loop 6h "fetch https://api.example.com/v1/prices and compare to the values in src/data/prices.json. If any price changed by more than 5%, update prices.json and create a commit with the changes. Log a summary of what changed."Claude fetches, diffs, and commits only when there is a meaningful change. No unnecessary commits.
Boris’s Workflow
Boris Cherny uses /loop to offload the cognitive overhead of code review management:
-
Auto-address reviews: A loop runs every 30 minutes checking for new PR review comments. Claude reads each comment, determines if it is a clear request (rename, refactor, add test) and addresses it directly — committing the fix and replying to the review thread.
-
PR hygiene: A separate loop checks for PRs that have been open more than 2 days without activity, pings the author, and adds a “needs-attention” label.
The result: PRs move faster without Boris manually tracking review state across multiple repos.
Gotchas
Machine must stay awake. If your laptop sleeps, the loop pauses. On macOS, use caffeinate to prevent sleep during a loop session:
caffeinate -i claude /loop 30m "my command"Intervals are approximate. The loop waits the full interval between the end of one run and the start of the next. A 30-minute loop with a 2-minute execution runs every 32 minutes, not exactly 30.
No parallel loops by default. Loops execute sequentially. If a run is still in progress when the next interval fires, the new run waits. This prevents concurrent file writes.
Log rotation. After 100 runs, older logs are archived to ~/.claude/loops/<loop-id>/archive/. The most recent 100 are always in runs/.
Token consumption. Each loop iteration consumes tokens. Long-running loops on large codebases can add up. Use --dry-run on the first interval to estimate token usage before committing to a 3-day loop.
/loop 1h "..." --dry-run # simulate one run, report estimated tokens