Background Tasks & Monitoring
After this lesson, you will be able to:
- Run long commands in background with `run_in_background: true` so your session doesn't block
- Use `Monitor` to stream events from a background process — line-by-line notifications without polling
- Schedule deferred work via `ScheduleWakeup` (dynamic /loop) and `CronCreate` (cron-style scheduling)
- Pick the right background pattern — fire-and-forget, monitor stream, scheduled wake-up, persistent cron
Before You Start
#Four Background Patterns
| Pattern | Use For | Example |
|---|---|---|
run_in_background: true | Long shell commands you'll check later | npm run build, pytest --slow, docker build |
Monitor | Stream events from a long-running process | Tail logs, watch test output, observe a deploy |
ScheduleWakeup | One-shot deferred work | "Check the build in 5 minutes", "Re-poll status" |
CronCreate | Recurring scheduled work | "Audit dependencies every Monday 9am" |
#run_in_background: Fire and Forget
Bash(
command="npm run build",
description="Production build",
run_in_background=True
)Returns immediately with a process handle. Claude continues working. When the build finishes, Claude gets a notification:
[notification] Background process #142 completed
Command: npm run build
Exit: 0
Duration: 4m 12s
Output: <truncated, available via Read>
Best for
- Long compiles / builds
- Test suites that take >2 minutes
- Docker image builds
- Deployments where you want to do other work meanwhile
Anti-pattern
- Quick commands (just block — overhead not worth it)
- Commands you need the output of immediately
- Sequential dependencies (use shell
&&instead)
#Monitor: Stream Events
When you want line-by-line awareness of a running process (not just "did it finish"):
# Start a long process
proc = Bash(
command="pytest tests/ -v",
run_in_background=True
)
# Monitor its output
Monitor(
process_id=proc.id,
pattern="FAILED|ERROR" # only notify on these lines
)You get a notification each time the pattern matches. Useful for:
- Watching a CI deploy log for failure markers
- Tailing a server log for error events
- Watching a training run for loss anomalies
- Polling-style "wait until X happens" without burning tokens
#Monitor: until-loop pattern
# Wait until a service is healthy, no polling tokens spent on each check
Monitor(
command="until curl -sf localhost:3000/health; do sleep 2; done",
description="Wait for dev server to be ready"
)Claude is notified once the server starts responding. Single notification, no token cost during the wait.
#ScheduleWakeup: One-Shot Deferred Work
/loop or "check back later" patterns:ScheduleWakeup(
delaySeconds=300,
reason="Check long-running build status",
prompt="<<autonomous-loop-dynamic>>"
)delaySeconds and runs the prompt. Useful for:- "Build will take 5 min — check it then"
- "Database migration in progress — verify in 10 min"
- Idle ticks on autonomous agents (default 1200–1800s)
<300s: cache stays warm — cheap>300s: cache miss on wake-up — pay once, but right for genuinely idle waits
Pick durations to match what you're waiting for, not round-number minutes.
#CronCreate: Recurring Scheduled Work
For autonomous agents that need to fire on a schedule:
CronCreate(
schedule="0 9 * * 1", # Monday 9am
prompt="Audit npm dependencies for new CVEs. File Linear tickets for any CRITICAL.",
reason="Weekly security audit"
)Cron-formatted schedule strings:
0 * * * *— every hour0 9 * * *— daily at 9am0 9 * * 1— Monday at 9am0 0 1 * *— first of every month
CronList, CronDelete.Use cases
- Weekly dep audits → file tickets for vulnerabilities
- Daily error-log triage → summarize Sentry events into a channel
- Hourly DB backup verification
- Nightly build of production-grade datasets
#Combining Patterns
#Pattern: Long build + parallel work
1. Start build in background (run_in_background)
2. Continue editing files in main session
3. When build notification arrives, react (deploy if pass, fix if fail)
#Pattern: Watch deploy logs
1. kubectl rollout status deployment/api --watch (run_in_background + Monitor)
2. Pattern: "Error|Failed|CrashLoopBackOff"
3. On match: notify, stop, investigate
4. On success: continue with smoke tests
#Pattern: Autonomous scheduled audit
CronCreate(
schedule="0 8 * * 1-5", # weekdays at 8am
prompt="""
1. Run /ultrareview on the develop branch since last Friday
2. Summarize critical findings
3. Post to #engineering Slack via slack MCP
""",
reason="Daily branch quality check"
)
#Pattern: Deferred follow-up after deploy
ScheduleWakeup(
delaySeconds=900, # 15 min — past cache window, but right for "settle then verify"
reason="Verify post-deploy metrics settled",
prompt="Query Grafana for error rate over last 15 min; compare to pre-deploy baseline; alert if elevated"
)
#Cost Awareness
Background patterns can save or burn tokens depending on usage:
| Action | Token Impact |
|---|---|
run_in_background for a 5-min build | Saves ~5 min of waiting tokens |
Monitor with pattern matching | Cheap — only fires on match |
ScheduleWakeup <300s | Cache warm — cheap |
ScheduleWakeup >300s | One cache miss + new turn cost |
CronCreate daily | Once/day = predictable cost |
| Polling loop (BAD) | Burns tokens on every check |
Rule: replace polling loops with Monitor patterns. Replace blocking waits with run_in_background.
#Headless Mode for Automation
Background patterns shine in headless mode:
# Cron job that runs Claude in headless mode for a scheduled task
0 8 * * 1-5 claude --headless --permission-mode dontAsk \
--prompt "Run /ultrareview on develop since Friday. Post results to Slack."
Combine with Docker for isolation:
docker run --rm \
-e ANTHROPIC_API_KEY \
-v $(pwd):/workspace \
ghcr.io/anthropics/claude-code:latest \
--headless --prompt "Run nightly tests; report failures"
#Key Takeaways
run_in_backgroundfor long shell commands. Claude continues working, gets notified on completionMonitorfor streaming events. Replaces polling loops, only fires on relevant pattern matchesScheduleWakeupfor one-shot deferred work. Respect cache windows: <270s warm, or >1200s amortizeCronCreatefor recurring scheduled agents. Weekly audits, daily triage, scheduled reports- Headless mode + cron + Claude Code = autonomous background agents
#Quick Check
You started a 7-minute Docker build. What's the right pattern?
Claude has just started a 7-minute integration test. What's the right move?