How to Set Up OpenClaw Cron Jobs (With Examples You Can Copy)
OpenClaw was previously known as Clawdbot and Moltbot. This guide applies to all versions.
Set up OpenClaw cron jobs with openclaw cron add. Three schedule types, copy-paste templates for backups, reminders, and health checks, plus how to debug failed runs.
Key takeaways
Create a cron job: tell your agent "remind me every morning at 9am" or use openclaw cron add. Three schedule types: at (one-shot), every (interval), and cron (standard expressions like 0 9 * * *). Jobs run in isolated sessions by default (fresh context, recommended) or the main session. Cron expressions use your Gateway host's local timezone. ISO timestamps without a timezone are treated as UTC.
OpenClaw Starter Kit: If you are just getting started, the OpenClaw Starter Kit bundles config templates, workspace file examples, and skills we actively use. It covers the setup steps in this guide.
Always review commands your agent suggests before approving them. Don't paste prompts from sources you don't trust.
Fixes when it breaks. Workflows when it doesn't.
OpenClaw guides, configs, and troubleshooting notes. Every two weeks.
Quick Reference
| Schedule Type | When to Use | Example |
|---|---|---|
at | One-time task | Remind me Friday at 5 PM |
every | Fixed interval | Back up git every hour |
cron | Precise recurring | Morning briefing at 7 AM weekdays |
| Cron Expression | Meaning |
|---|---|
0 7 * * * | Every day at 7:00 AM (host timezone) |
0 7 * * 1-5 | Weekdays at 7:00 AM (host timezone) |
0 7 * * 1 | Every Monday at 7:00 AM (host timezone) |
*/30 * * * * | Every 30 minutes |
0 */6 * * * | Every 6 hours |
0 0 1 * * | First day of each month at midnight |
| Interval (ms) | Duration |
|---|---|
60000 | 1 minute |
300000 | 5 minutes |
1800000 | 30 minutes |
3600000 | 1 hour |
21600000 | 6 hours |
86400000 | 24 hours |
Need help with cron expressions? Use crontab.guru to build and test them.
OpenClaw Cron Command Reference
Every openclaw cron subcommand in one place. Copy-paste ready.
openclaw cron list Command
Lists all registered cron jobs with their status, schedule, and last run info.
openclaw cron listOutput example:
ID Name Schedule Enabled Last Run Status
ecae2e71-1331-4ebf-94ab-cc643e550cfe Daily Research 0 16 * * * PT false 2026-02-20 16:00 ok
0b09f1c2-bb79-4145-b2bc-570800bbbeb1 Morning Report 30 6 * * * PT true 2026-02-28 06:30 ok
a1b2c3d4-e5f6-7890-abcd-ef1234567890 Git Backup every 3600000ms true 2026-02-28 14:00 okEach row shows the job ID (use this for other commands), name, schedule expression, enabled state, last run timestamp, and last run status.
openclaw cron add Command Syntax
Create a new cron job from the CLI.
# Cron schedule (recurring at specific times)
openclaw cron add \
--name "Job Name" \
--cron "0 7 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "What the agent should do" \
--announce
# Interval schedule (recurring at fixed intervals)
openclaw cron add \
--name "Backup" \
--every 3600000 \
--session isolated \
--message "Run git backup"
# One-time schedule
openclaw cron add \
--name "Reminder" \
--at "2026-03-15T16:00:00Z" \
--session main \
--system-event "Check the deployment" \
--delete-after-runKey flags:
| Flag | Description |
|---|---|
--name | Human-readable job name |
--cron | Cron expression (5 fields: min hour dom mon dow) |
--every | Interval in milliseconds |
--at | ISO 8601 timestamp for one-time jobs |
--tz | Timezone for cron expressions (e.g., America/Los_Angeles) |
--session | isolated (fresh context) or main (with history) |
--message | Agent turn message (for isolated sessions) |
--system-event | System event text (for main session) |
--announce | Send output to the active channel |
--delete-after-run | Remove the job after it runs once |
--wake | Wake mode: now, next-heartbeat |
openclaw cron disable Command
Pause a job without deleting it. The job keeps its config and run history.
# Disable a job
openclaw cron disable <jobId>
# Re-enable it later
openclaw cron enable <jobId>Use openclaw cron list to find the job ID. Disabled jobs show Enabled: false in the list.
Other Cron Commands
# Check scheduler status
openclaw cron status
# Run a job immediately (for testing)
openclaw cron run <jobId>
# View run history for a job
openclaw cron runs --id <jobId>
# Edit an existing job
openclaw cron edit <jobId>
# Delete a job permanently
openclaw cron rm <jobId>Command Quick Reference
| Command | What it does |
|---|---|
openclaw cron status | Show scheduler status |
openclaw cron list | List all jobs |
openclaw cron add | Create a new job |
openclaw cron edit <id> | Edit an existing job |
openclaw cron run <id> | Run a job now (testing) |
openclaw cron runs --id <id> | View run history |
openclaw cron enable <id> | Enable a disabled job |
openclaw cron disable <id> | Disable without deleting |
openclaw cron rm <id> | Delete a job permanently |
Cron jobs.json Format
All cron jobs are stored in ~/.openclaw/cron/jobs.json. The file has this structure:
{
"version": 1,
"jobs": [
{
"id": "uuid-string",
"agentId": "main",
"name": "Job Name",
"enabled": true,
"createdAtMs": 1770197218926,
"updatedAtMs": 1770197218926,
"schedule": {
"kind": "cron",
"expr": "0 7 * * *",
"tz": "America/Los_Angeles"
},
"sessionTarget": "isolated",
"wakeMode": "next-heartbeat",
"payload": {
"kind": "agentTurn",
"message": "What the agent should do",
"timeoutSeconds": 600,
"model": "anthropic/claude-sonnet-4-6"
},
"state": {
"lastRunAtMs": 1770197300000,
"lastStatus": "ok",
"lastDurationMs": 45000,
"consecutiveErrors": 0
},
"delivery": {
"mode": "announce",
"channel": "telegram",
"to": "chat-id-or-topic",
"bestEffort": true
}
}
]
}Required fields: id, name, schedule, sessionTarget, payload, enabled.
Schedule object variants:
{"kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles"}for cron expressions{"kind": "every", "everyMs": 3600000}for intervals{"kind": "at", "at": "2026-03-15T16:00:00Z"}for one-time
Payload object variants:
{"kind": "agentTurn", "message": "..."}for isolated sessions{"kind": "systemEvent", "text": "..."}for main session
Optional payload fields: timeoutSeconds (max run time), model (override the default model for this job).
State object: Managed automatically. Shows last run time, status (ok or error), duration, and consecutive error count.
Delivery object: Controls where output goes. mode can be announce, webhook, or none. For announce, specify channel and optionally to (specific chat/topic ID).
You rarely need to edit jobs.json directly. The CLI commands handle creation and updates. But knowing the format helps when debugging or bulk-editing jobs.
OpenClaw Cron Jobs Configuration
Cron jobs are configured through two paths:
- CLI commands (
openclaw cron add,openclaw cron edit) for creating and managing individual jobs - Direct file editing (
~/.openclaw/cron/jobs.json) for bulk changes or advanced configuration
The cron scheduler runs inside the OpenClaw gateway process. When the gateway starts, it reads jobs.json and schedules all enabled jobs. Changes made through the CLI take effect immediately. If you edit jobs.json directly, restart the gateway to pick up changes:
openclaw gateway restartGateway-level cron settings in ~/.openclaw/config/config.json:
{
"cron": {
"enabled": true
}
}If cron.enabled is false or missing, the scheduler does not start and no jobs run. This is the first thing to check if all your cron jobs suddenly stop firing.
Schedule Types
at: run once
Fires once at a specific date and time, then it's done.
{
"schedule": {
"kind": "at",
"at": "2026-02-28T09:00:00Z"
}
}Use for: one-off reminders, deployment checks, deadline alerts. Note: one-shot jobs auto-delete after they run successfully. Use --keep-after-run in the CLI or set "deleteAfterRun": false in the job config to keep them.
every: fixed interval
Runs repeatedly at a set interval in milliseconds.
{
"schedule": {
"kind": "every",
"everyMs": 3600000
}
}Use for: git backups, data syncs, health checks. Anything where exact clock time doesn't matter.
cron: standard expressions
Standard cron syntax. Five fields: minute, hour, day-of-month, month, day-of-week.
{
"schedule": {
"kind": "cron",
"expr": "0 7 * * *",
"tz": "America/Los_Angeles"
}
}Use for: morning briefings, weekly reports, monthly cleanups. Anything that needs to fire at a specific time.
Timezone: Cron expressions use your Gateway host's local timezone by default. Add "tz": "America/New_York" to be explicit (recommended, especially on VPS instances where the host timezone might be UTC). For at schedules, ISO timestamps without an explicit timezone offset are treated as UTC.
Creating Jobs
By chatting
Tell your agent what you want. It creates the job.
"Create a cron job that runs every morning at 7 AM Pacific. Check my dashboard for overnight items and send me a briefing."
The agent parses the intent, picks the right schedule type, creates the job, and confirms back. If something is ambiguous, it asks.
You can also manage jobs through chat:
- "List all my cron jobs"
- "Disable the morning briefing"
- "Delete the weekly report job"
- "Change the briefing to 6:30 AM instead"
Through the CLI
# Check scheduler status
openclaw cron status
# Add a recurring isolated job with delivery
openclaw cron add \
--name "Morning brief" \
--cron "0 7 * * *" \
--tz "America/Los_Angeles" \
--session isolated \
--message "Summarize overnight updates." \
--announce
# Add a one-shot reminder (auto-deletes after success)
openclaw cron add \
--name "Reminder" \
--at "2026-03-15T16:00:00Z" \
--session main \
--system-event "Reminder: check the deployment" \
--wake now \
--delete-after-run
# List all jobs
openclaw cron list
# Edit an existing job
openclaw cron edit <jobId>
# Run a job immediately (for testing)
openclaw cron run <jobId>
# View run history
openclaw cron runs --id <jobId>
# Enable / disable without deleting
openclaw cron enable <jobId>
openclaw cron disable <jobId>
# Delete a job permanently
openclaw cron rm <jobId>Where jobs are stored
~/.openclaw/cron/jobs.json. You rarely need to edit this directly, but it's useful for debugging.
Session Targeting
Every cron job runs in either the main session or an isolated session.
Isolated session (recommended)
Fresh context every run. No conversation history. The agent only knows what's in the job payload and workspace files.
{
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "Check the dashboard for overnight items and send a briefing."
}
}Use for: most jobs. Morning briefings, backups, monitoring, syncs, reports.
Main session
Runs with full conversation history. The agent knows what you discussed yesterday.
{
"sessionTarget": "main",
"payload": {
"kind": "systemEvent",
"text": "Run the weekly review using context from this week's conversations."
}
}Use for: jobs that explicitly need conversation context. This is rare. If you keep reaching for main session, move the context into workspace files instead.
Key constraint: Main session requires systemEvent payload. Isolated session requires agentTurn payload.
Delivery (where output goes)
Isolated jobs need somewhere to send their output. Three delivery modes:
announce(default for isolated jobs): sends output to a chat channel. Add"delivery": {"mode": "announce", "channel": "telegram"}to target a specific channel.webhook: POSTs the result to a URL. Use"delivery": {"mode": "webhook", "to": "https://your-endpoint.com/hook"}.none: job runs silently with no delivery.
If you omit delivery on an isolated job, it defaults to announce. This is the most common source of "my cron job runs but I don't see the output" issues: the announce target defaults to the last active channel, which might not be where you expect it.
Copy-Paste Examples
Morning briefing (7 AM weekdays)
{
"name": "Morning Briefing",
"schedule": { "kind": "cron", "expr": "0 7 * * 1-5", "tz": "America/Los_Angeles" },
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "Check today's calendar, scan inbox for overnight items, review any unfinished tasks, and send me a briefing."
},
"delivery": { "mode": "announce", "channel": "telegram" },
"enabled": true
}For a complete walkthrough of building this, see the morning briefing setup guide.
Hourly git backup
{
"name": "Git Backup",
"schedule": { "kind": "every", "everyMs": 3600000 },
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "Run git add -A in the workspace, commit with a timestamp if there are changes, and push to remote. Skip if nothing changed."
},
"enabled": true
}Weekly cost report (Monday 8 AM)
{
"name": "Weekly Cost Report",
"schedule": { "kind": "cron", "expr": "0 8 * * 1", "tz": "America/Los_Angeles" },
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "Calculate total LLM spend by model for the past 7 days. Compare against last week. Flag any anomalies or unexpected cost spikes. Send the report."
},
"enabled": true
}One-time reminder
{
"name": "Deployment Check",
"schedule": { "kind": "at", "at": "2026-03-15T17:00:00Z" },
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "Check if the deployment from this morning is still healthy. Verify the homepage loads and report any issues."
},
"enabled": true
}Debugging
Job doesn't run:
- Check it exists:
openclaw cron listor inspect~/.openclaw/cron/jobs.json - Check it's enabled: look for
"enabled": true - Check the schedule: cron expressions use your host's local timezone. On a VPS, that's often UTC. Add an explicit
tzfield if unsure. - Check run history:
openclaw cron runs --id <jobId>to see if it ran and what happened - Check the logs:
openclaw gateway logsor~/.openclaw/logs/
Job runs but produces no output:
- Test the payload manually first. Paste the message text into chat and see if it works interactively.
- Check session targeting. If you used
isolatedbut the task needs conversation context, it won't have it. - Check delivery configuration. The job might run but send output to the wrong channel.
Job runs but fails:
- Check logs for error details
- Most common: vague payload. "Check on things" fails. "Pull calendar events from Google Calendar API, filter for external meetings, send to the briefing channel" works.
- Token limits: complex tasks in isolated sessions might exceed a single turn. Simplify the payload or break it into multiple jobs.
Job costs more than expected:
- Check frequency.
60000ms is 1 minute, not 1 hour. A job that costs $0.02 per run at 1-minute intervals is $28.80/day. - Check model routing. Jobs default to your configured model. Use a cheaper model for simple tasks if your setup supports model overrides.
Common Mistakes
| Mistake | What Happens | Fix |
|---|---|---|
| Wrong interval units | $0.02/run x every minute = $28.80/day | Double-check ms values against the table above |
| No timezone on a VPS | Cron uses host timezone (often UTC on VPS) | Add "tz": "America/Your_Timezone" explicitly |
| Vague payload | Agent interprets differently each run | Write specific, actionable instructions |
| Testing in main, running in isolated | Works in chat, fails as cron job | Test the exact payload in an isolated session first |
| Too many jobs at the same time | Resource contention, slow execution | Stagger by 5 minutes: 7:00, 7:05, 7:10 |
| Not monitoring costs | Surprise bill at end of month | Set up a cost tracking job first |
Cost Control
Every cron job that invokes an LLM costs tokens. Simple shell-only jobs (git commit, file cleanup) cost nothing in LLM fees.
Before you schedule anything:
- Calculate: cost per run x runs per day x 30
- A $0.05 job running every 6 hours = $0.20/day = $6/month
- A $0.05 job running every 5 minutes = $14.40/day = $432/month
Keep costs down:
- Use isolated sessions (smaller context = fewer tokens)
- Write specific payloads (less reasoning = fewer tokens)
- Use cheaper models for simple tasks when possible
- Start with daily frequency and increase only if needed
If you're running OpenClaw on a VPS, the best cheap VPS guide covers hosting costs alongside operational costs. The security hardening playbook includes monitoring setup that helps track runaway jobs.
Key Terms
Cron expression is a five-field schedule format (minute, hour, day, month, weekday) used to define when recurring jobs run.
Isolated session is a fresh agent session with no conversation history, used for self-contained cron jobs.
Session target determines whether a cron job runs with full conversation context (main) or a clean slate (isolated).
FAQ
How many cron jobs can I run?
No hard limit. 5 to 20 is manageable without performance or budget issues. The practical limit is your token budget and server resources.
Do cron jobs cost money?
Only if they invoke an LLM. Shell-only jobs (git, file operations) are free. Jobs that require the agent to reason, search, or generate content cost the same as an equivalent chat interaction.
What happens if a cron job fails?
The failure is logged. Depending on your setup, the agent may notify you. The job stays enabled and tries again at the next scheduled time. It does not retry immediately.
Can I use cron jobs with subagents?
Yes. A cron job payload can instruct the agent to spawn subagents for complex tasks. Useful for parallel workflows like running multiple research queries simultaneously.
How do I stop all cron jobs at once?
Ask your agent to "disable all cron jobs." This pauses every job without deleting them. Re-enable individually when ready.
Can cron jobs post to social media?
Yes, if your agent has API access or browser control. Be careful with fully autonomous posting. Review content before enabling unattended social media automation.
Related Resources
- OpenClaw Morning Briefing: 10-Minute Setup: Complete walkthrough of the most popular cron job
- Using Telegram Groups with OpenClaw: Route cron output to dedicated channels
- OpenClaw Pairing Explained: Why your cron job might not deliver messages (pairing issues)
- The Proven Security Hardening Playbook: Includes monitoring setup for runaway jobs
- Best Cheap VPS for OpenClaw: Hosting costs for always-on cron jobs
- Docker OpenClaw Done Right: Container setup for isolated cron environments
- OpenClaw Documentation: Cron Jobs: Official reference
- Crontab.guru: Build and test cron expressions
Changelog
- 2026-02-13: Initial publication
- 2026-02-24: Updated hero image
- 2026-02-27: Major restructure for reference intent. Added quick-reference tables, copy-paste JSON configs, cost control section, common mistakes table. Removed tutorial narrative in favor of scannable format. Added cross-links and Related Resources section. Fixed timezone defaults (cron uses host local timezone, not UTC). Fixed CLI commands to match actual OpenClaw CLI (rm, enable, disable, edit). Added delivery configuration section. Added full cron add syntax with flags.
- 2026-03-01: Added complete command reference section: openclaw cron list, cron add syntax with flags table, cron disable, command quick reference table, jobs.json format with full schema, cron jobs configuration section covering gateway-level settings.
- 2026-03-22: Added resource link to OpenClaw Starter Kit
Fixes when it breaks. Workflows when it doesn't.
OpenClaw guides, configs, and troubleshooting notes. Every two weeks.



