Scheduling

A headless agent can't start itself. Something has to fire it. That something is either a scheduler (fires at a time) or a trigger (fires on an event). This page is about picking the right one for your task, and the operational details that separate an agent that runs forever from one that silently breaks on a Tuesday.

Schedulers vs. triggers. The shape of the choice.

Every scheduled agent is one of two architectures:

~ scheduler or trigger - pick one ~

When in doubt: if the work happens at a known time, scheduler. If the work happens in response to something else, trigger. A few workflows benefit from both (scheduled cleanup plus event-based urgent runs), but start with one.

Time-based scheduling options.

Cron. The old reliable.

A crontab entry on a server that runs your agent script at fixed times:

# Every weekday at 9am, generate the daily report
0 9 * * 1-5 /usr/local/bin/claude-daily-report.sh

Pros: simple, free, works everywhere there's Unix. Cons: single-node (cron dies, agent dies). No retry on failure by default. Monitoring is your problem. Good for personal use or small setups; not great for business-critical.

Claude Code's /loop and /schedule.

Claude Code has built-in recurring-run skills. /loop 5m /my-skill runs a skill every 5 minutes while Claude Code is open. /schedule can set up server-side triggers. Convenient for development; not a replacement for a real production scheduler.

Managed cloud schedulers.

Google Cloud Scheduler, AWS EventBridge, Cloudflare Cron Triggers. All managed services that trigger HTTP endpoints on a schedule. You pay a few cents a month; you get retry, monitoring, and HA out of the box. This is the right choice for anything you actually depend on.

Event-based trigger options.

Webhooks.

Another service emits an event (new email, new GitHub issue, new Stripe charge); your endpoint catches it and fires the agent. The cleanest model when the source system supports it.

Polling-to-event.

If the source doesn't do webhooks, you poll it on a schedule, diff against last-seen state, and fire the agent only on changes. More work than webhooks but more general.

Message queues.

Redis streams, SQS, RabbitMQ, etc. Multiple agent workers consume from the queue, one per message. This is the pattern for high-volume or multi-tenant agent work where you need to process many events concurrently without overloading any single agent.

The right cadence for the task.

~ cadence → architecture ~

What a scheduled run needs to get right.

Four properties separate agents that survive from agents that cause incidents:

~ four design rules for scheduled runs ~

What happens when runs overlap.

At some point, run N hasn't finished when run N+1 is scheduled. You need to decide what happens:

Pick the behavior explicitly. Default "skip" until you have a reason to change.

Observability. The difference between "runs fine" and "broken for three weeks."

Scheduled agents are invisible. You don't sit and watch them. If something goes wrong, you don't find out until a human notices the report didn't arrive. That's weeks of silent failure sometimes.

Fix this with three instruments:

The implementation checklist.

  1. Pick scheduler-type (time or event) based on the task shape.
  2. Pick cadence; use the table above.
  3. Make the run idempotent (last-run markers, deduping).
  4. Set --max-turns and a wall-clock timeout.
  5. Decide overlap policy (skip / queue / parallel).
  6. Wire up a heartbeat service.
  7. Turn on cost alerting, tagged by agent.
  8. Save outputs somewhere queryable.
  9. Run manually once. Fix what breaks. THEN schedule it.
  10. Review the logs weekly for the first month. Pattern-match for drift.

Every item is cheap. Skipping any of them is how scheduled agents cause real problems.