#Do cron tasks require heartbeats?
1 messages · Page 1 of 1 (latest)
No — cron jobs do not require heartbeats.
- Heartbeat = “poke the main session every N minutes and let the agent decide what to do”
- Cron = “run this specific job on a schedule”
So disabling heartbeat won’t stop cron from firing.
If your cron jobs didn’t run, the usual causes are:
- Gateway wasn’t running continuously (cron runs inside the Gateway process; if the gateway is down/asleep at the scheduled time, it won’t run)
- Cron is disabled (
cron.enabled: false) or env varOPENCLAW_SKIP_CRONis set - Timezone mismatch (job
--tzvs host timezone)
Debug commands (most useful):
openclaw --version
openclaw gateway status
openclaw cron run <jobId> --force
openclaw cron runs --id <jobId> --limit 50
openclaw logs --follow
Docs:
- https://docs.openclaw.ai/automation/cron-vs-heartbeat
- https://docs.openclaw.ai/help/faq#cron-or-reminders-do-not-fire-what-should-i-check
If you paste your openclaw --version + the output of openclaw cron runs --id <jobId> --limit 50, I can usually tell immediately what happened.
HOw to show the list of cron tasks? I don't know the jobIds
Run this on the Gateway host (or in remote mode pointing at it):
openclaw cron list
Helpful variants:
openclaw cron list --all # include disabled jobs too
openclaw cron list --json # easier to copy/paste here
openclaw cron status # shows whether the scheduler is running
The jobId is what openclaw cron list prints for each entry.
One nuance since you mentioned heartbeats: if a job is --session main and its wake mode is effectively “next heartbeat”, then disabling heartbeats can indeed prevent it from running. If you paste openclaw cron list --json (and openclaw --version), I can tell you which kind you have.
openclaw cron list --json
{
"jobs": [
{
"id": "b54baf8a-6033-4dcd-980e-56f87c288ff1",
"agentId": "reminders",
"sessionKey": "agent:reminders:telegram:group:-5219108434",
"name": "Amazon return reminder (2d)",
"enabled": true,
"deleteAfterRun": true,
"createdAtMs": 1772522355012,
"updatedAtMs": 1772522355012,
"schedule": {
"kind": "at",
"at": "2026-03-15T14:00:00.000Z"
},
"sessionTarget": "main",
"wakeMode": "now",
"payload": {
"kind": "systemEvent",
"text": "Reminder: Your Amazon return is due Mar 17, 2026 (in 2 days). Return all listed items before the deadline."
},
"state": {
"nextRunAtMs": 1773583200000
}
},
{
"id": "e4ff3c0c-bb40-4c00-b980-abda31788607",
"agentId": "reminders",
"sessionKey": "agent:reminders:telegram:group:-5219108434",
"name": "Amazon return reminder (1d)",
"enabled": true,
"deleteAfterRun": true,
"createdAtMs": 1772522355019,
"updatedAtMs": 1772522355019,
"schedule": {
"kind": "at",
"at": "2026-03-16T14:00:00.000Z"
},
"sessionTarget": "main",
"wakeMode": "now",
"payload": {
"kind": "systemEvent",
"text": "Reminder: Your Amazon return is due tomorrow (Mar 17, 2026). Final day to prepare and drop off with the QR code at Whole Foods."
},
"state": {
"nextRunAtMs": 1773669600000
}
},
...
openclaw --version
2026.3.2
Those jobs actually look fine — they just haven’t fired yet.
Example:
"at": "2026-03-15T14:00:00.000Z"→ next run is Mar 15, 14:00 UTC- Today (from your message timestamp) is Mar 14, so nothing should have happened yet.
A couple important details based on your JSON:
- These are main-session cron jobs:
"sessionTarget": "main"+"payload.kind": "systemEvent"
Main-session cron jobs run via the heartbeat runner (they enqueue a system event and then “wake” a heartbeat run).
Because yours are "wakeMode": "now", they should still run at the scheduled time even if you don’t have periodic heartbeats running all day — but they do still depend on that heartbeat mechanism existing.
- Timezone gotcha:
- The
--attimestamps are stored as ISO withZ(UTC).