Both heartbeats and cron jobs let you run tasks on a schedule. This guide helps you choose the right mechanism for your use case.
| Use Case | Recommended | Why |
|---|---|---|
| Check inbox every 30 min | Heartbeat | Batches with other checks, context-aware |
| Send daily report at 9am sharp | Cron (isolated) | Exact timing needed |
| Monitor calendar for upcoming events | Heartbeat | Natural fit for periodic awareness |
| Run weekly deep analysis | Cron (isolated) | Standalone task, can use different model |
| Remind me in 20 minutes | Cron (main, --at) |
One-shot with precise timing |
| Background project health check | Heartbeat | Piggybacks on existing cycle |
Heartbeats run in the main session at a regular interval (default: 30 min). They’re designed for the agent to check on things and surface anything important.
HEARTBEAT_OK and no message is delivered.# Heartbeat checklist
- Check email for urgent messages
- Review calendar for events in next 2 hours
- If a background task finished, summarize results
- If idle for 8+ hours, send a brief check-in
The agent reads this on each heartbeat and handles all items in one turn.
{
agents: {
defaults: {
heartbeat: {
every: "30m", // interval
target: "last", // where to deliver alerts
activeHours: { start: "08:00", end: "22:00" }, // optional
},
},
},
}
See Heartbeat for full configuration.
Cron jobs run at precise times and can run in isolated sessions without affecting main context. Recurring top-of-hour schedules are automatically spread by a deterministic per-job offset in a 0-5 minute window.
--at.--stagger <duration> or force exact timing with --exact.cron:<jobId> without polluting main history.announce (summary); choose none as needed.--at for precise future timestamps.coderclaw cron add \
--name "Morning briefing" \
--cron "0 7 * * *" \
--tz "America/New_York" \
--session isolated \
--message "Generate today's briefing: weather, calendar, top emails, news summary." \
--model opus \
--announce \
--channel whatsapp \
--to "+15551234567"
This runs at exactly 7:00 AM New York time, uses Opus for quality, and announces a summary directly to WhatsApp.
coderclaw cron add \
--name "Meeting reminder" \
--at "20m" \
--session main \
--system-event "Reminder: standup meeting starts in 10 minutes." \
--wake now \
--delete-after-run
See Cron jobs for full CLI reference.
Does the task need to run at an EXACT time?
YES -> Use cron
NO -> Continue...
Does the task need isolation from main session?
YES -> Use cron (isolated)
NO -> Continue...
Can this task be batched with other periodic checks?
YES -> Use heartbeat (add to HEARTBEAT.md)
NO -> Use cron
Is this a one-shot reminder?
YES -> Use cron with --at
NO -> Continue...
Does it need a different model or thinking level?
YES -> Use cron (isolated) with --model/--thinking
NO -> Use heartbeat
The most efficient setup uses both:
HEARTBEAT.md (checked every 30 min):
# Heartbeat checklist
- Scan inbox for urgent emails
- Check calendar for events in next 2h
- Review any pending tasks
- Light check-in if quiet for 8+ hours
Cron jobs (precise timing):
# Daily morning briefing at 7am
coderclaw cron add --name "Morning brief" --cron "0 7 * * *" --session isolated --message "..." --announce
# Weekly project review on Mondays at 9am
coderclaw cron add --name "Weekly review" --cron "0 9 * * 1" --session isolated --message "..." --model opus
# One-shot reminder
coderclaw cron add --name "Call back" --at "2h" --session main --system-event "Call back the client" --wake now
Lobster is the workflow runtime for multi-step tool pipelines that need deterministic execution and explicit approvals. Use it when the task is more than a single agent turn, and you want a resumable workflow with human checkpoints.
For scheduled workflows, use cron or heartbeat to trigger an agent turn that calls Lobster. For ad-hoc workflows, call Lobster directly.
lobster CLI) in tool mode and returns a JSON envelope.needs_approval, you resume with a resumeToken and approve flag.tools.alsoAllow: ["lobster"] (recommended).lobsterPath, it must be an absolute path.See Lobster for full usage and examples.
Both heartbeat and cron can interact with the main session, but differently:
| Â | Heartbeat | Cron (main) | Cron (isolated) |
|---|---|---|---|
| Session | Main | Main (via system event) | cron:<jobId> |
| History | Shared | Shared | Fresh each run |
| Context | Full | Full | None (starts clean) |
| Model | Main session model | Main session model | Can override |
| Output | Delivered if not HEARTBEAT_OK |
Heartbeat prompt + event | Announce summary (default) |
Use --session main with --system-event when you want:
coderclaw cron add \
--name "Check project" \
--every "4h" \
--session main \
--system-event "Time for a project health check" \
--wake now
Use --session isolated when you want:
coderclaw cron add \
--name "Deep analysis" \
--cron "0 6 * * 0" \
--session isolated \
--message "Weekly codebase analysis..." \
--model opus \
--thinking high \
--announce
| Mechanism | Cost Profile |
|---|---|
| Heartbeat | One turn every N minutes; scales with HEARTBEAT.md size |
| Cron (main) | Adds event to next heartbeat (no isolated turn) |
| Cron (isolated) | Full agent turn per job; can use cheaper model |
Tips:
HEARTBEAT.md small to minimize token overhead.target: "none" on heartbeat if you only want internal processing.