Cron vs Heartbeat: When to Use Each
Both heartbeats and cron jobs let you run tasks on a schedule. This guide helps you choose the right mechanism for your use case.Quick Decision Guide
| 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 |
Heartbeat: Periodic Awareness
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.When to use heartbeat
- Multiple periodic checks: Instead of 5 separate cron jobs checking inbox, calendar, weather, notifications, and project status, a single heartbeat can batch all of these.
- Context-aware decisions: The agent has full main-session context, so it can make smart decisions about what’s urgent vs. what can wait.
- Conversational continuity: Heartbeat runs share the same session, so the agent remembers recent conversations and can follow up naturally.
- Low-overhead monitoring: One heartbeat replaces many small polling tasks.
Heartbeat advantages
- Batches multiple checks: One agent turn can review inbox, calendar, and notifications together.
- Reduces API calls: A single heartbeat is cheaper than 5 isolated cron jobs.
- Context-aware: The agent knows what you’ve been working on and can prioritize accordingly.
- Smart suppression: If nothing needs attention, the agent replies
HEARTBEAT_OKand no message is delivered. - Natural timing: Drifts slightly based on queue load, which is fine for most monitoring.
Heartbeat example: HEARTBEAT.md checklist
Configuring heartbeat
Cron: Precise Scheduling
Cron jobs run at exact times and can run in isolated sessions without affecting main context.When to use cron
- Exact timing required: “Send this at 9:00 AM every Monday” (not “sometime around 9”).
- Standalone tasks: Tasks that don’t need conversational context.
- Different model/thinking: Heavy analysis that warrants a more powerful model.
- One-shot reminders: “Remind me in 20 minutes” with
--at. - Noisy/frequent tasks: Tasks that would clutter main session history.
- External triggers: Tasks that should run independently of whether the agent is otherwise active.
Cron advantages
- Exact timing: 5-field cron expressions with timezone support.
- Session isolation: Runs in
cron:<jobId>without polluting main history. - Model overrides: Use a cheaper or more powerful model per job.
- Delivery control: Can deliver directly to a channel; still posts a summary to main by default (configurable).
- No agent context needed: Runs even if main session is idle or compacted.
- One-shot support:
--atfor precise future timestamps.
Cron example: Daily morning briefing
Cron example: One-shot reminder
Decision Flowchart
Combining Both
The most efficient setup uses both:- Heartbeat handles routine monitoring (inbox, calendar, notifications) in one batched turn every 30 minutes.
- Cron handles precise schedules (daily reports, weekly reviews) and one-shot reminders.
Example: Efficient automation setup
HEARTBEAT.md (checked every 30 min):Lobster: Deterministic workflows with approvals
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.When Lobster fits
- Multi-step automation: You need a fixed pipeline of tool calls, not a one-off prompt.
- Approval gates: Side effects should pause until you approve, then resume.
- Resumable runs: Continue a paused workflow without re-running earlier steps.
How it pairs with heartbeat and cron
- Heartbeat/cron decide when a run happens.
- Lobster defines what steps happen once the run starts.
Operational notes (from the code)
- Lobster runs as a local subprocess (
lobsterCLI) in tool mode and returns a JSON envelope. - If the tool returns
needs_approval, you resume with aresumeTokenandapproveflag. - The tool is an optional plugin; you must allowlist
lobsterintools.allow. - If you pass
lobsterPath, it must be an absolute path.
Main Session vs Isolated Session
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 | Summary posted to main |
When to use main session cron
Use--session main with --system-event when you want:
- The reminder/event to appear in main session context
- The agent to handle it during the next heartbeat with full context
- No separate isolated run
When to use isolated cron
Use--session isolated when you want:
- A clean slate without prior context
- Different model or thinking settings
- Output delivered directly to a channel (summary still posts to main by default)
- History that doesn’t clutter main session
Cost Considerations
| 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 |
- Keep
HEARTBEAT.mdsmall to minimize token overhead. - Batch similar checks into heartbeat instead of multiple cron jobs.
- Use
target: "none"on heartbeat if you only want internal processing. - Use isolated cron with a cheaper model for routine tasks.