Skip to main content

Claude Code Cron

When should an agent poll — and when should it wait to be asked?


Cron

FactDetail
WhatRecurring prompts on a schedule. A cron job fires a slash command at fixed intervals.
WhereCronCreate / CronList / CronDelete tools inside Claude Code
Pattern*/5 * * * * — prompt: /my-command — fires every 5 minutes
Catch-upFires once when idle, not per missed interval. Not a queue — a heartbeat.

Good Use Cases

Active monitoring where latency matters and messages are expected within minutes.

ScenarioWhy Cron Works
Waiting for engineering response to a decision you just postedResponse expected in minutes, you need to act on it
Monitoring a deploy or CI runState changes fast, you need to catch failure early
Active handoff sessionBoth sides online, messages flowing, coordination needed
Babysitting a long-running processProcess will complete soon, you need the result

Bad Use Cases

Ambient polling of async channels. The catch-up behavior means messages sit until the next session regardless — cron adds noise, not speed.

ScenarioWhy Cron Fails
Polling a comms channel that gets 2-3 messages per hour10+ empty ticks burn context window for zero value
Background monitoring during deep workInterrupts flow state for "no messages" reports
Default-on schedulingCreates noise when quiet, wastes tokens, trains you to ignore output
Watching for async events with no time pressureManual check when you're ready to act is always sufficient

The Comms Loop Lesson

Built a /comms-loop command that auto-created a 5-minute cron on first run. In practice: fired 10+ times against an empty channel in one session. Every tick consumed context window tokens to report nothing.

Root cause: Confused two concerns — comms operations (read, send, ask) and background monitoring (cron). Bundling them meant you couldn't read messages without starting ambient polling.

Fix: Split the concerns.

TriggerBehavior
/comms-loopOne-shot: health check, read, plan check, report
/comms-loop watchOpt-in: start 5-minute cron for active monitoring
/comms-loop stopKill the cron

Principle: Manual invocation is always sufficient for async channels. Cron is for time-sensitive monitoring where you need to catch a state change within minutes.


Decision Rule

Before creating a cron job, answer:

  1. Will the next message require action within 5 minutes? If no — manual check is fine.
  2. Is the source likely to produce a message in the next 30 minutes? If no — you're polling silence.
  3. Does missing a message by 10 minutes matter? If no — wait until you're ready to act.

If all three are no, skip the cron. Run the command manually when you need the information.


Implementation

# Create — opt-in, with clear purpose
CronCreate: */5 * * * * — "/comms-loop"

# List — verify what's running
CronList

# Delete — clean up when monitoring is done
CronDelete: <job-id>

Convention: Commands that support cron should offer explicit watch and stop subcommands rather than auto-scheduling. The user decides when polling adds value.

Context

  • Claude Code — Concepts, config, enforcement hierarchy
  • Tools — Tool calling, programmatic patterns, scoring pipeline
  • Plans — Task DAGs, phases, quality gates
  • Skills — Reusable procedures with quality gates

Questions

When does scheduled automation cross from useful to wasteful?

  • What's the token cost per empty cron tick, and how many empty ticks justify removing the cron?
  • Could event-driven triggers (webhooks, filesystem watchers) replace polling entirely?
  • What patterns separate "I need this now" from "I'll check when I'm ready"?