πŸ”
Tools & AutomationChapter 23 of 33Β· 8 min read

Chapter 23: Cron, Heartbeat & Scheduled Tasks

OpenClaw has two complementary systems for running the agent automatically without user interaction: Cron jobs (fire once at a precise scheduled time) and Heartbeats (periodic self-checks that run within the main session). This chapter covers both β€” when to use each, how to configure them, and how to minimize API costs.


Cron vs Heartbeat: Which to Use?

CronHeartbeat
TriggerExact scheduled timeEvery N minutes, continuously
SessionNew isolated session each runRuns inside the main session
Use caseOne-off reports, briefings, remindersOngoing monitoring, ambient awareness
CostPer-run token costCan be very cheap with lightContext
DeliveryAny channel or webhookSends only when something needs attention

Part 1: Cron Jobs

What Are Cron Jobs?

A cron job is a pre-defined prompt that fires at an exact scheduled time. The agent processes it like a user message and delivers the response to a configured destination.

Common use cases:

  • Daily standup: Summarize yesterday's GitHub activity and Jira tickets every morning
  • Status reports: Check server health every hour and alert if something is wrong
  • Weekly digest: Compile the week's messages and decisions from Slack into a summary
  • Data monitoring: Check a dashboard or database and report anomalies
  • Content generation: Create a daily social media post draft every morning

Defining a Cron Job

{
  "cron": {
    "tasks": [
      {
        "id": "morning-briefing",
        "name": "Morning Team Briefing",
        "schedule": "0 8 * * 1-5",
        "workspace": "dev-team",
        "agent": "balanced",
        "prompt": "Summarize: 1) Any GitHub PRs opened or merged in the last 24 hours. 2) Any Jira tickets updated yesterday. 3) Today's date and any calendar events. Be concise.",
        "deliverTo": {
          "channel": "slack",
          "destination": "C01TEAMCHANNEL"
        }
      }
    ]
  }
}

Cron Schedule Syntax

β”Œβ”€β”€β”€β”€β”€ minute (0–59)
β”‚ β”Œβ”€β”€β”€β”€β”€ hour (0–23)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€ day of month (1–31)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€ month (1–12)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€ day of week (0–7, 0 and 7 = Sunday)
β”‚ β”‚ β”‚ β”‚ β”‚
* * * * *
ScheduleExpression
Every minute* * * * *
Every hour0 * * * *
Every day at 8 AM0 8 * * *
Weekdays at 9 AM0 9 * * 1-5
Every Monday at 10 AM0 10 * * 1
First of every month0 0 1 * *
Every 15 minutes*/15 * * * *

Delivery Targets

{ "deliverTo": { "channel": "telegram", "destination": "chat_id" } }
{ "deliverTo": { "channel": "slack", "destination": "C01CHANNELID" } }
{ "deliverTo": { "webhook": "https://hooks.example.com/abc", "method": "POST" } }
{ "deliverTo": { "logOnly": true } }

Conditional Delivery

Only deliver when the agent finds something worth reporting:

{
  "id": "error-monitor",
  "schedule": "*/10 * * * *",
  "prompt": "Check /var/log/app.log for the last 10 minutes. Reply CLEAR if no errors, or describe any ERROR entries found.",
  "deliverTo": { "channel": "telegram", "destination": "${ADMIN_CHAT_ID}" },
  "deliverIf": "response does not contain CLEAR"
}

Task Variables

VariableValue
{{date}}Today's date (YYYY-MM-DD)
{{time}}Current time (HH:MM)
{{datetime}}Full ISO datetime
{{weekday}}Day name (Monday, Tuesday…)
{{week_number}}ISO week number

Managing Cron Jobs via CLI

openclaw cron list
openclaw cron run morning-briefing      # Test immediately
openclaw cron pause morning-briefing
openclaw cron resume morning-briefing
openclaw cron delete morning-briefing
openclaw cron history morning-briefing

Timezone Configuration

{
  "cron": {
    "timezone": "Asia/Karachi",
    "tasks": [...]
  }
}

Error Handling

{
  "cron": {
    "onError": {
      "retry": 3,
      "retryDelay": 300,
      "alertChannel": "telegram",
      "alertDestination": "${ADMIN_CHAT_ID}"
    }
  }
}

Part 2: Heartbeat

What Is Heartbeat?

Heartbeat is OpenClaw's proactive awareness system. Unlike cron (which fires once and delivers a report), heartbeat runs periodic agent turns inside the main session so the agent can surface anything that needs attention β€” without spamming you when everything is fine.

The key idea: the agent reads a checklist file (HEARTBEAT.md) at regular intervals. If all is well, it replies HEARTBEAT_OK and you hear nothing. If something needs your attention, it sends you a message.

The Cost Advantage Over Cron

If you have 5 things to monitor every 30 minutes, cron requires 5 separate agent calls Γ— 48 runs/day = 240 API calls/day. One heartbeat with 5 items in its checklist = 1 call Γ— 48 runs/day = 48 API calls/day β€” an 80% cost reduction.

Enabling Heartbeat

{
  "agents": {
    "defaults": {
      "heartbeat": {
        "every": "30m",
        "target": "last",
        "activeHours": {
          "start": "09:00",
          "end": "22:00",
          "timezone": "Asia/Karachi"
        }
      }
    }
  }
}
FieldDescription
everyInterval: "30m", "1h", "15m". Set "0m" to disable.
targetWhere to send alerts: "none" (internal only), "last" (last-used channel)
activeHoursOnly run during these hours (with timezone). Silent outside this window.

The HEARTBEAT_OK Protocol

When the agent has nothing to report, it starts or ends its reply with HEARTBEAT_OK. OpenClaw sees this token and silently drops the message β€” you receive no notification. Only when something actually needs attention does a message reach you.

The default ackMaxChars is 300: if the reply contains HEARTBEAT_OK and the remaining content is under 300 characters, it's considered an acknowledgment and dropped.

{
  "heartbeat": {
    "every": "30m",
    "ackMaxChars": 300,
    "showOk": false,
    "showAlerts": true
  }
}

The HEARTBEAT.md Checklist

Create ~/.openclaw/HEARTBEAT.md to define what the agent checks on each tick:

# Heartbeat Checklist

Check the following every 30 minutes:

- [ ] Are there any new messages in the admin Telegram group that need a response?
- [ ] Are any GitHub Actions workflows currently failing?
- [ ] Is disk usage on the server above 85%?
- [ ] Are there any Stripe payment failures in the last 30 minutes?
- [ ] Any critical error logs in /var/log/app.log?

If all clear, reply: HEARTBEAT_OK
If anything needs attention, describe it clearly and send an alert.

The agent reads this file on each heartbeat tick. You can update the checklist anytime and the agent picks up the changes on the next tick.

Cost Optimization

For busy gateways, these two settings dramatically reduce heartbeat cost:

{
  "heartbeat": {
    "every": "30m",
    "isolatedSession": true,
    "lightContext": true
  }
}
SettingEffect
isolatedSession: trueEach heartbeat runs in a fresh session β€” no conversation history to process. Reduces token cost from ~100K to ~2–5K per run.
lightContext: trueOnly loads HEARTBEAT.md from bootstrap files, not the full config and skill context.

Use a cheaper model specifically for heartbeats:

{
  "agents": {
    "my-agent": {
      "provider": "anthropic",
      "model": "claude-sonnet-4-6",
      "heartbeat": {
        "model": "claude-haiku-4-5-20251001",
        "isolatedSession": true,
        "lightContext": true
      }
    }
  }
}

Task-Based Heartbeat Items

Instead of checking everything every tick, schedule individual checklist items on their own intervals:

# HEARTBEAT.md

tasks:
  - check: "Any new Stripe failures?"
    every: 15m
  - check: "Weekly sales summary ready?"
    every: 1w
    at: "Monday 09:00"
  - check: "Server disk usage above 80%?"
    every: 1h

Only tasks that are due on the current tick are included in the agent's context, further reducing cost.

Manual Heartbeat Trigger

# Trigger a heartbeat immediately for testing
openclaw system event --text "Run heartbeat now" --mode now

Visibility Controls

{
  "heartbeat": {
    "showOk": false,
    "showAlerts": true,
    "useIndicator": true,
    "includeReasoning": false
  }
}

useIndicator: true shows a small status indicator in the Control UI even when HEARTBEAT_OK β€” a visual pulse that confirms the agent is alive without sending notifications.


Choosing: Cron or Heartbeat?

Use cron when:

  • You need a report delivered at an exact time (daily briefing at 9 AM)
  • The task has a clear end (generate this week's summary)
  • You want isolated, independent task runs

Use heartbeat when:

  • You need continuous ambient awareness (is anything wrong right now?)
  • You want to consolidate multiple monitoring checks into one efficient call
  • You only want to be notified when something actually needs attention

Use both together for complete coverage: heartbeat for ongoing monitoring, cron for scheduled reports.


Next: Chapter 24 β€” Building Custom Skills β€” How to write your own skills from scratch and integrate any API or service into your OpenClaw gateway.