# Heartbeat & Cron Job Configuration

Canonical: https://clawdocx.com/docs/heartbeat-config
Author: Sam Okafor
Difficulty: INTERMEDIATE
Published: 2026-02-24
Updated: 2026-09-19

> Understand OpenClaw's heartbeat system: optimize it for cost and performance, configure active hours, set up cron jobs, and monitor autonomous behavior.

## What Is the Heartbeat?

The heartbeat is OpenClaw's internal clock, a periodic cycle where the agent "wakes up" and thinks about what it should be doing. During each heartbeat, the agent:

1. **Checks for pending tasks**: reminders, scheduled actions, follow-ups
2. **Evaluates its environment**: new emails, calendar events, system status
3. **Processes background skills**: skills that run on a schedule rather than on demand
4. **Maintains awareness**: the agent reflects on recent interactions and plans ahead

Think of it as the agent's autonomous thinking cycle. Without the heartbeat, your agent only responds when spoken to. With it, the agent proactively checks things, sends reminders, and stays aware of its surroundings.

> **Note**
>
> The heartbeat is what makes OpenClaw an autonomous agent rather than a simple chatbot. It allows proactive behavior, the agent can message you unprompted when it has something important to share.

---

## Default Configuration and Cost Implications

By default, the heartbeat fires every **10 minutes** using whatever model is configured as default. This has significant cost implications.

### The Cost Problem

Each heartbeat cycle sends a prompt to your LLM provider. Let's do the math:

| Interval | Cycles/Day | Using Opus 4.6 (~$0.05/cycle) | Using Sonnet 4.6 (~$0.01/cycle) | Using Haiku 4 (~$0.003/cycle) |
|----------|-----------|------------------------------|-------------------------------|----------------------------------|
| 5 min | 288 | $14.40/day | $2.88/day | $0.86/day |
| 10 min | 144 | $7.20/day | $1.44/day | $0.43/day |
| 15 min | 96 | $4.80/day | $0.96/day | $0.29/day |
| 30 min | 48 | $2.40/day | $0.48/day | $0.14/day |
| 60 min | 24 | $1.20/day | $0.24/day | $0.07/day |

> **Danger**
>
> The default 10-minute heartbeat with Claude Opus 4.6 costs approximately $216/month in API calls alone, just for the heartbeat, before any user interactions. This is the most common surprise expense for new OpenClaw users.

### Recommended Configuration

For most users, the optimal heartbeat configuration is:

```json
{
  "heartbeat": {
    "enabled": true,
    "interval_minutes": 15,
    "model": "claude-haiku-4-20260210",
    "max_tokens": 1024,
    "active_hours": {
      "start": "08:00",
      "end": "23:00",
      "timezone": "America/New_York"
    },
    "sleep_interval_minutes": 60
  }
}
```

This configuration:
- Uses Claude Haiku 4 for heartbeats (cheap but capable)
- Runs every 15 minutes during active hours
- Slows to every 60 minutes during sleep hours
- Costs approximately $5-8/month

---

## Configuring the Heartbeat

### Basic Heartbeat Settings

Edit `~/.openclaw/openclaw.json`. There is no `openclaw config edit`; `openclaw config file` "Prints the active config file path" so you open the right one, and `openclaw config set <key> <value>` changes a single key without an editor at all.

```bash
openclaw config file
```

```json
{
  "heartbeat": {
    "enabled": true,
    "interval_minutes": 15,
    "model": "claude-haiku-4-20260210"
  }
}
```

### Heartbeat Model Selection

The heartbeat does not need your most powerful model. Its job is to:
- Check if reminders are due
- Scan for new events
- Decide if anything needs attention
- Escalate to the full model only when necessary

**Claude Haiku 4** is ideal for this because it is:
- Fast (responds in under 1 second)
- Cheap ($1/1M input tokens vs $15/1M for Opus)
- Capable enough for triage and simple decisions

If the heartbeat detects something that needs deeper reasoning, it triggers a full processing cycle using your default model (e.g., Sonnet 4.6).

### Escalation Configuration

```json
{
  "heartbeat": {
    "model": "claude-haiku-4-20260210",
    "escalation_model": "claude-sonnet-4-6-20260217",
    "escalate_on": [
      "pending_reminder",
      "new_email_important",
      "calendar_event_soon",
      "skill_alert",
      "user_mentioned"
    ]
  }
}
```

---

## Active Hours

Active hours define when your agent is most responsive. During active hours, the heartbeat runs at the configured interval. Outside active hours (sleep period), it runs at a slower rate.

### Configuration

```json
{
  "heartbeat": {
    "active_hours": {
      "start": "07:00",
      "end": "23:00",
      "timezone": "America/Los_Angeles",
      "days": ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
    },
    "interval_minutes": 15,
    "sleep_interval_minutes": 60
  }
}
```

### Day-Specific Schedules

You can set different schedules for different days:

```json
{
  "heartbeat": {
    "schedules": [
      {
        "days": ["mon", "tue", "wed", "thu", "fri"],
        "start": "07:00",
        "end": "22:00",
        "interval_minutes": 10
      },
      {
        "days": ["sat", "sun"],
        "start": "09:00",
        "end": "23:00",
        "interval_minutes": 30
      }
    ],
    "sleep_interval_minutes": 120,
    "timezone": "America/New_York"
  }
}
```

This runs more frequent heartbeats on weekdays (every 10 minutes from 7 AM to 10 PM) and less frequent on weekends (every 30 minutes from 9 AM to 11 PM).

> **Tip**
>
> Active hours do not affect your ability to message the agent. You can always send a message at any time, and the agent will respond. Active hours only control the autonomous heartbeat frequency.

---

## Disabling the Heartbeat

If you want a purely reactive agent (only responds when messaged), disable the heartbeat:

```json
{
  "heartbeat": {
    "enabled": false
  }
}
```

This eliminates heartbeat API costs entirely. The trade-off is that your agent will not:
- Send proactive reminders
- Check for new emails or events autonomously
- Execute time-based skills
- Run cron jobs (cron jobs depend on the heartbeat)

---

## Cron Jobs

Cron jobs let you schedule specific tasks to run at defined times. They are more targeted than the general heartbeat, each cron job has a specific task with a specific schedule.

### Adding a Cron Job via CLI

```bash
openclaw cron add "Summarize my unread emails" --schedule "0 8 * * *" --model claude-sonnet-4-6-20260217
```

This creates a cron job that runs every day at 8:00 AM, summarizing unread emails using Sonnet 4.

### Cron Schedule Syntax

OpenClaw uses standard cron syntax:

```
┌───────── minute (0-59)
│ ┌─────── hour (0-23)
│ │ ┌───── day of month (1-31)
│ │ │ ┌─── month (1-12)
│ │ │ │ ┌─ day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *
```

**Common schedules:**

| Schedule | Cron Expression | Description |
|----------|----------------|-------------|
| Every morning at 8 AM | `0 8 * * *` | Daily morning brief |
| Every hour | `0 * * * *` | Hourly check-in |
| Weekdays at 9 AM | `0 9 * * 1-5` | Workday morning |
| Sunday at 7 PM | `0 19 * * 0` | Weekly review |
| Every 30 minutes | `*/30 * * * *` | Frequent monitoring |
| First of month at noon | `0 12 1 * *` | Monthly report |

### Managing Cron Jobs

**List all cron jobs:**

```bash
openclaw cron list
```

Output:

```
ID   Schedule        Model          Task
1    0 8 * * *       sonnet-4.6     Summarize my unread emails
2    0 9 * * 1-5     haiku-4        Check my calendar and tell me what's happening today
3    0 20 * * 0      sonnet-4.6     Write a weekly summary of what we accomplished
4    */30 * * * *    haiku-4        Check if any important emails arrived
```

**Remove a cron job:**

```bash
openclaw cron remove 3
```

**Pause a cron job:** there is no `cron pause` or `cron resume`. Pausing and resuming are `disable` and `enable`, and the docs say to "Use `openclaw automations enable <job-id>` to resume scheduled runs."

```bash
openclaw cron disable 4
```

**Resume a paused cron job:**

```bash
openclaw cron enable 4
```

### Cron Job Configuration in JSON

You can also define cron jobs directly in `openclaw.json`:

```json
{
  "cron": {
    "jobs": [
      {
        "id": 1,
        "task": "Summarize my unread emails and send the summary to me",
        "schedule": "0 8 * * *",
        "model": "claude-sonnet-4-6-20260217",
        "channel": "telegram",
        "enabled": true
      },
      {
        "id": 2,
        "task": "Check my calendar and brief me on today's events",
        "schedule": "0 9 * * 1-5",
        "model": "claude-haiku-4-20260210",
        "channel": "telegram",
        "enabled": true
      },
      {
        "id": 3,
        "task": "Scan Hacker News for AI-related stories and send me the top 5",
        "schedule": "0 12 * * *",
        "model": "claude-sonnet-4-6-20260217",
        "channel": "discord",
        "enabled": true
      }
    ],
    "timezone": "America/New_York",
    "max_concurrent": 2,
    "retry_on_failure": true,
    "retry_delay_minutes": 5
  }
}
```

---

## Example Cron Job Workflows

### Morning Briefing

```
Schedule: 0 7 * * * (7:00 AM daily)
Model: claude-sonnet-4-6-20260217
Task: "Good morning! Check my calendar for today's events, summarize
any important unread emails from overnight, check the weather forecast,
and give me a brief summary of top tech news. Keep it concise."
```

### End-of-Day Review

```
Schedule: 0 18 * * 1-5 (6:00 PM weekdays)
Model: claude-sonnet-4-6-20260217
Task: "Wrap up my day. Tell me what tasks I completed today,
what's still pending, and what's on my calendar for tomorrow."
```

### Weekly Planning

```
Schedule: 0 20 * * 0 (8:00 PM Sundays)
Model: claude-opus-4-6-20260217
Task: "It's Sunday evening. Review everything we discussed and
accomplished this week. Create a summary and suggest priorities
for next week."
```

### Health Monitoring

```
Schedule: */15 * * * * (every 15 minutes)
Model: claude-haiku-4-20260210
Task: "Quick check: Is everything running smoothly? Check for any
system alerts or important notifications. Only message me if
something needs attention."
```

> **Tip**
>
> For the health monitoring cron, set the model to Haiku and instruct the agent to only message you if something is wrong. This keeps costs minimal while providing continuous monitoring.

---

## Monitoring Heartbeat and Cron Execution

### View Heartbeat History

There is no `openclaw heartbeat` command group and no `--last` flag. The documented reader is `openclaw system heartbeat last`, whose siblings are `enable` and `disable`, and which "always print the raw RPC JSON payload".

```bash
openclaw system heartbeat last
```

Output:

```
Time                 Model       Tokens  Actions Taken
2026-02-20 08:00:01  haiku-4     312     Triggered morning briefing cron
2026-02-20 08:15:00  haiku-4     245     No action needed
2026-02-20 08:30:01  haiku-4     289     Sent reminder: dentist at 2pm
2026-02-20 08:45:00  haiku-4     201     No action needed
...
```

### View Cron Execution History

There is no `cron history`. Run history is `runs`, where "`automations runs` is the preferred spelling. `cron runs` and the leaf-local `--id <job-id>` form remain supported compatibility aliases."

```bash
openclaw cron runs <job-id> --limit 50
```

```
ID  Time                 Status   Model       Tokens  Duration
1   2026-02-20 08:00:03  Success  sonnet-4.6  2,451   4.2s
2   2026-02-20 09:00:01  Success  haiku-4     892     1.1s
3   2026-02-20 12:00:02  Failed   sonnet-4.6  —       timeout
```

### Monitor Costs

There is no top-level `openclaw usage` and no `--breakdown` flag. `openclaw gateway usage-cost` takes `--days`, `--agent`, `--all-agents` and `--json`, so scope it to the agent that owns the heartbeat:

```bash
openclaw gateway usage-cost --days 7 --agent <id>
```

```
Heartbeat API Usage (Last 7 Days)
=================================
Total cycles:    672
Total tokens:    198,432
Estimated cost:  $2.38

By model:
  claude-haiku-4:     648 cycles, 182,400 tokens, $0.91
  claude-sonnet-4.6:   24 cycles,  16,032 tokens, $1.65

Cron job costs:
  Morning briefing:    $0.84/week
  Calendar check:      $0.21/week
  News scan:           $0.42/week
```

---

## Cost Optimization Tips for Heartbeat

1. **Use Haiku 4 for heartbeat**: It is 10-20x cheaper than Opus and fast enough for triage
2. **Increase the interval**: 15-30 minutes is sufficient for most users
3. **Set active hours**: No need to run frequent heartbeats at 3 AM
4. **Use escalation**: Let Haiku decide when to invoke a more capable model
5. **Minimize cron jobs**: Each cron job is an additional API call
6. **Use "only notify if important" instructions**: Reduce unnecessary responses

See the [Cost Optimization Guide](/docs/cost-optimization) for comprehensive strategies.

---

## Troubleshooting

### Heartbeat not firing

```bash
openclaw doctor --check heartbeat
```

Common causes:
- Heartbeat is disabled in configuration
- Gateway is not running
- API key is invalid or rate-limited

### Cron jobs not executing

- Verify the cron schedule syntax is correct
- Check that the job is enabled (`openclaw cron list`)
- Ensure the heartbeat is enabled (cron jobs are processed during heartbeat cycles)
- Check the Gateway logs for errors with `openclaw logs --follow`, since there is no `openclaw gateway logs` subcommand

### Cron jobs running at wrong times

- Verify the timezone is set correctly in the cron configuration
- Check system timezone: `date +%Z`
- The `timezone` field in configuration must be a valid IANA timezone name (e.g., `America/New_York`, not `EST`)

---

## Next Steps

- **[Cost Optimization](/docs/cost-optimization)**: detailed cost control strategies
- **[API Key Setup](/docs/api-key-setup)**: model configuration and routing
- **[Skills Explained](/docs/skills-explained)**: skills that run on heartbeat schedules
- **[Troubleshooting](/docs/troubleshooting)**: fix common heartbeat issues

## Sources

- [OpenClaw: Config](https://docs.openclaw.ai/cli/config)
- [OpenClaw: Automations (cron)](https://docs.openclaw.ai/cli/cron)
- [OpenClaw: System](https://docs.openclaw.ai/cli/system)
- [OpenClaw: Logs](https://docs.openclaw.ai/cli/logs)
- [OpenClaw: Query a running Gateway](https://docs.openclaw.ai/cli/gateway/query)