OpenClaw Cron Jobs: How to Schedule Automated Tasks (2026)
Step-by-step guide to scheduling cron jobs in OpenClaw. Set up automated briefings, email checks, and data pulls — no DevOps background needed.
OpenClaw runs cron jobs natively. You define a schedule, a prompt, and a channel. OpenClaw fires it at the exact time — every day, every hour, or once a week. No external scheduler needed.
This guide covers how to configure them, what they're good for, and the 3 mistakes that silently break automated tasks.
What OpenClaw Cron Jobs Actually Do
A cron job in OpenClaw is a scheduled message sent to a Claude session. The session runs your instructions, uses tools if you've configured them, and delivers output to a channel — Telegram, Discord, email, or webhook.
Practical examples that teams run daily:
- Morning brief at 8:00 AM — pulls calendar, emails, weather, Slack mentions
- EOD digest at 6:00 PM — summarizes what shipped, what blocked, what's due tomorrow
- Weekly SEO rank check — pulls DataForSEO rankings, highlights movements >3 positions
- Lead counter at noon — queries Supabase, reports new signups since yesterday
- Server health check every 30 minutes — pings endpoints, alerts if any 5xx responses
The key difference from a standard cron: OpenClaw cron tasks have AI context. They don't just run a script — they interpret results and write a human summary.
How to Set Up a Cron Job
OpenClaw cron configuration lives in your workspace's HEARTBEAT.md or as explicit cron entries in your OpenClaw config. Two approaches exist:
Approach 1: HEARTBEAT.md (Simplest)
Create HEARTBEAT.md in your workspace root. OpenClaw polls it on every heartbeat interval (default: 30 minutes). Write plain instructions — the agent reads them and acts.
# HEARTBEAT.md
## Morning Brief (08:00 ET)
- Check unread emails — summarize anything urgent
- Pull today's calendar — list events with times
- Check RAM usage — alert if above 80%
- Report yesterday's Supabase signups
## EOD Summary (18:00 ET)
- List git commits pushed today
- Summarize open Nerve board tasks
- Flag anything overdue
No YAML. No cron syntax. Write what you want done. The agent figures out the rest.
Approach 2: Explicit Cron Config
For precise timing and isolated sessions, use OpenClaw's cron config block. This spawns a fresh agent session at an exact time — separate from your main chat session.
cron:
- schedule: "0 8 * * *" # 8:00 AM UTC daily
prompt: "Run morning brief. Check email, calendar, RAM. Post to Telegram."
channel: telegram
model: haiku # Use Haiku for cron — saves budget
timeout: 300
- schedule: "*/30 * * * *" # Every 30 minutes
prompt: "Check server health. Ping mrdelegate.ai, blog/, api/. Alert if any fail."
channel: telegram
model: haiku
The schedule field accepts standard cron syntax. The model field lets you use Claude Haiku for routine checks — about 20x cheaper than Sonnet for background tasks.
The 3 Mistakes That Break Cron Jobs Silently
Mistake 1: Not Testing in Cron Context
The most common failure: a script works when you run it manually but silently fails in cron. The root cause is environment variables.
When cron runs a command, it uses a minimal shell environment. source commands that work in your terminal don't work in cron. The fix:
# WRONG - silently fails in cron
source /root/mrdelegate/.env
node check-health.js
# CORRECT - works in cron
bash -c 'set -a; source /root/mrdelegate/.env; set +a; node /root/mrdelegate/check-health.js'
Always test your cron command by running exactly this in a fresh terminal with no active shell session.
Mistake 2: No Log File
Without logging, you have no idea if cron ran, what it returned, or why it failed. Add a log path to every cron entry:
0 8 * * * bash -c 'set -a; source /root/.env; set +a; node /root/morning-brief.js' >> /var/log/mrdelegate-morning.log 2>&1
The 2>&1 redirects stderr too. Check logs after the first run:
tail -f /var/log/mrdelegate-morning.log
Mistake 3: Cron Sends No Test Message
After fixing a cron job, developers check the log says "no errors" and call it done. Wrong. The log can show success while the Telegram/Discord delivery failed silently.
Rule: after any cron change, trigger a test run and confirm the message arrives in the target channel. Watch the channel. See the message. Then mark it done.
Practical Cron Job Examples
Daily Lead Counter
- schedule: "0 9 * * *"
prompt: |
Query Supabase table 'signups' for rows created in the last 24 hours.
Count total, calculate change vs 7-day average.
Post to Telegram: "Leads today: X (7-day avg: Y)"
channel: telegram
model: haiku
Weekly SEO Rank Check
- schedule: "0 7 * * 1" # Every Monday 7 AM
prompt: |
Check DataForSEO rankings for keywords: "openclaw hosting", "openclaw setup guide", "managed openclaw".
Compare to last week's data in memory.
Report any movement over 3 positions. Flag drops immediately.
channel: telegram
model: sonnet # More complex analysis — worth Sonnet
Server Health Monitor (Every 30 Min)
- schedule: "*/30 * * * *"
prompt: |
Ping these URLs: https://mrdelegate.ai/, https://mrdelegate.ai/blog/, https://mrdelegate.ai/sitemap.xml
If any return non-200, immediately alert Telegram with exact URL and status code.
If all healthy, stay silent (no message).
channel: telegram
model: haiku
silent_on_ok: true
The silent_on_ok: true flag suppresses messages when everything is fine. You only hear about problems.
Debugging Cron Jobs
When a cron job stops working, run this checklist:
- Check the log file — did it run at all? Missing entries = cron daemon issue or syntax error
- Verify cron syntax — use crontab.guru to validate your schedule expression
- Test the command manually — copy the exact command from crontab and run it in a fresh terminal
- Check env vars — run
env | grep YOUR_VARto confirm the variable is accessible - Check systemd —
journalctl -u cron -n 50shows cron daemon activity
90% of failures come from items 2-4. Fix those first before assuming OpenClaw itself is broken.
Cron vs Heartbeat: Which to Use
OpenClaw gives you two scheduling mechanisms. They're not interchangeable.
Use cron when:
- Exact timing matters (payroll at 9:00 AM sharp)
- The task needs isolation from your main chat session
- You want output delivered directly to a channel without your session's context
- One-shot future reminders ("run this in 2 hours")
Use HEARTBEAT.md when:
- Multiple checks should batch together
- Timing can drift (every ~30 min is fine)
- You want context from recent messages in the same session
- You need to batch 4-5 periodic checks into a single API call
For most teams: HEARTBEAT.md handles 80% of recurring tasks. Reserve explicit cron for precise timing requirements.
Cost Management for Cron
Every cron job fires an API call. With aggressive scheduling, costs add up. Budget guidelines:
- Every 5 minutes, Haiku: ~$2/month for a simple health check
- Every 30 minutes, Haiku: ~$0.40/month for a digest
- Daily, Sonnet: ~$0.30-1.50/month depending on complexity
- Weekly, Sonnet: ~$0.05-0.20/month
A well-configured OpenClaw setup with 8-10 cron jobs costs $3-6/month in API calls. Far less than a VA checking email manually.