> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wednesdayai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Cron vs Heartbeat

# 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                 |
| Cheap check, wake persona only if it finds work | Wake-gate (cron or heartbeat) | Gate the expensive turn behind a cheap check |

## Heartbeat: Periodic Awareness

Heartbeats run against a configured session at a regular interval (default: 30 min).
By default that is the **main session**. Set `isolatedSession: true` when the
heartbeat should make the same delivery decision from the base session but run
the model in a fresh `:heartbeat` sibling transcript.

### 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 can use the configured session context, or a lightweight isolated heartbeat context when you want to avoid transcript churn.
* **Conversational continuity**: Heartbeat delivery can still target the base conversation even when `isolatedSession: true` keeps heartbeat turns out of that transcript.
* **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_OK` and no message is delivered.
* **Natural timing**: Drifts slightly based on queue load, which is fine for most monitoring.

### Heartbeat example: HEARTBEAT.md checklist

```md theme={"dark"}
# 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.

### Configuring heartbeat

```json5 theme={"dark"}
{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m", // interval
        target: "last", // explicit alert delivery target (default is "none")
        lightContext: true,
        isolatedSession: true,
        skipWhenBusy: true,
        activeHours: { start: "08:00", end: "22:00" }, // optional
      },
    },
  },
}
```

See [Heartbeat](/gateway/heartbeat) for full configuration.

## Cron: Precise Scheduling

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.

### 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

* **Precise timing**: 5-field or 6-field (seconds) cron expressions with timezone support.
* **Built-in load spreading**: recurring top-of-hour schedules are staggered by up to 5 minutes by default.
* **Per-job control**: override stagger with `--stagger <duration>` or force exact timing with `--exact`.
* **Session isolation**: Runs in `cron:<jobId>` without polluting main history.
* **Model overrides**: Use a cheaper or more powerful model per job.
* **Delivery control**: Isolated jobs default to `announce` (summary); choose `none` as needed.
* **Immediate delivery**: Announce mode posts directly without waiting for heartbeat.
* **No agent context needed**: Runs even if main session is idle or compacted.
* **One-shot support**: `--at` for precise future timestamps.

### Cron example: Daily morning briefing

```bash theme={"dark"}
openclaw 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.

### Cron example: One-shot reminder

```bash theme={"dark"}
openclaw 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](/automation/cron-jobs) for full CLI reference.

## Decision Flowchart

```bash theme={"dark"}
Does the task need to run at an EXACT time?
  YES -> Use cron
  NO  -> Continue...

Does the task need isolation from the active conversation transcript?
  YES -> Use heartbeat with isolatedSession for periodic awareness, or cron (isolated) for standalone work
  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
```

## Combining Both

The most efficient setup uses **both**:

1. **Heartbeat** handles routine monitoring (inbox, calendar, notifications) in one batched turn every 30 minutes.
2. **Cron** handles precise schedules (daily reports, weekly reviews) and one-shot reminders.

### Example: Efficient automation setup

**HEARTBEAT.md** (checked every 30 min):

```md theme={"dark"}
# 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):

```bash theme={"dark"}
# Daily morning briefing at 7am
openclaw cron add --name "Morning brief" --cron "0 7 * * *" --session isolated --message "..." --announce

# Weekly project review on Mondays at 9am
openclaw cron add --name "Weekly review" --cron "0 9 * * 1" --session isolated --message "..." --model opus

# One-shot reminder
openclaw cron add --name "Call back" --at "2h" --session main --system-event "Call back the client" --wake now
```

## 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.

For scheduled workflows, use cron or heartbeat to trigger an agent turn that calls Lobster.
For ad-hoc workflows, call Lobster directly.

### Operational notes (from the code)

* Lobster runs as a **local subprocess** (`lobster` CLI) in tool mode and returns a **JSON envelope**.
* If the tool returns `needs_approval`, you resume with a `resumeToken` and `approve` flag.
* The tool is an **optional plugin**; enable it additively via `tools.alsoAllow: ["lobster"]` (recommended).
* Lobster expects the `lobster` CLI to be available on `PATH`.

See [Lobster](/tools/lobster) for full usage and examples.

## Main Session vs Isolated Session

Both heartbeat and cron can interact with the main session, but differently:

|         | Heartbeat                                          | Cron (main)              | Cron (isolated)            |
| ------- | -------------------------------------------------- | ------------------------ | -------------------------- |
| Session | Main or configured base; optional isolated sibling | Main (via system event)  | `cron:<jobId>`             |
| History | Shared by default; fresh with `isolatedSession`    | Shared                   | Fresh each run             |
| Context | Full by default; lightweight with `lightContext`   | Full                     | None (starts clean)        |
| Model   | Heartbeat or main session model                    | Main session model       | Can override               |
| Output  | Delivered if not `HEARTBEAT_OK`                    | Heartbeat prompt + event | Announce summary (default) |

### 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

```bash theme={"dark"}
openclaw cron add \
  --name "Check project" \
  --every "4h" \
  --session main \
  --system-event "Time for a project health check" \
  --wake now
```

### When to use isolated cron

Use `--session isolated` when you want:

* A clean slate without prior context
* Different model or thinking settings
* Announce summaries directly to a channel
* History that doesn't clutter main session

```bash theme={"dark"}
openclaw cron add \
  --name "Deep analysis" \
  --cron "0 6 * * 0" \
  --session isolated \
  --message "Weekly codebase analysis..." \
  --model opus \
  --thinking high \
  --announce
```

## Nudge and wake-gate jobs

Both heartbeat and cron can run a **cheap check** that wakes the agent's main persona only when the
check finds something worth acting on — the [nudge contract](/gateway/heartbeat#nudge-wake-the-main-persona).
Use this when "is there anything to do?" is cheap to answer but the response is expensive.

| You want                                           | Use                                                         |
| -------------------------------------------------- | ----------------------------------------------------------- |
| A check on the heartbeat cadence, gating each turn | Heartbeat `wakeGate`                                        |
| A check at an exact time / fixed cron schedule     | Cron `wakeGate` payload                                     |
| A one-off external trigger from a script           | [`openclaw agent nudge`](/cli/agent-nudge)                  |
| A typed payload from a plugin or hook              | [`api.runtime.signals.nudge`](/plugins/agent-signals#nudge) |

A **heartbeat wake-gate** turns the periodic heartbeat into a gate: it runs the cheap check first
and skips the persona turn (reason `wake-gate-empty`) when the check is negative. See
[Heartbeat](/gateway/heartbeat#wake-gate-gate-the-expensive-persona-turn).

A **cron wake-gate** job runs at a precise schedule, fires the same kind of cheap check, and nudges
the main session only on a positive result. The job uses `sessionTarget: "main"` with a
`wakeGate` payload (a forward-only cron store kind — ADR 0015):

```json5 theme={"dark"}
{
  // cron job store shape (created via the gateway / control panel; see Cron jobs)
  name: "Inbox gate",
  sessionTarget: "main",
  schedule: { kind: "every", everyMs: 900000 },
  payload: {
    kind: "wakeGate",
    reason: "inbox",
    gate: {
      kind: "command",
      command: "node ./check-inbox.mjs",
    },
  },
}
```

On a positive gate the cron runner nudges the main session with the gate text; on a negative gate
the run is recorded as skipped and no persona turn happens. Like every nudge, the result is
silent-unless-it-decides and honours all busy/active-hours gates.
Cron also forwards job cancellation into the gate and the immediate heartbeat wake. If a scheduled
or manual run is stopped, command/model checks are cancelled with the job instead of continuing in
the background.

See [Cron jobs](/automation/cron-jobs) for the full payload reference.

## 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          |

**Tips**:

* Keep `HEARTBEAT.md` small 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.

## Related

* [Heartbeat](/gateway/heartbeat) - full heartbeat configuration
* [Cron jobs](/automation/cron-jobs) - full cron CLI and API reference
* [System](/cli/system) - system events + heartbeat controls
