Skip to content

How to Set Up OpenClaw Cron Jobs (With Examples You Can Copy)

·8 min read·By Christopher Kvamme

OpenClaw was previously known as Clawdbot and Moltbot. Configuration and commands depend on the version in use.

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.

How to Set Up OpenClaw Cron Jobs (With Examples You Can Copy)
Share:
On this page

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.

Quick Reference

Schedule TypeWhen to UseExample
atOne-time taskRemind me Friday at 5 PM
everyFixed intervalBack up git every hour
cronPrecise recurringMorning briefing at 7 AM weekdays
Cron ExpressionMeaning
0 7 * * *Every day at 7:00 AM (host timezone)
0 7 * * 1-5Weekdays at 7:00 AM (host timezone)
0 7 * * 1Every 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
600001 minute
3000005 minutes
180000030 minutes
36000001 hour
216000006 hours
8640000024 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.

bash

openclaw cron list

Output example:

text

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  ok

Each 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.

bash

# 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-run

Key flags:

FlagDescription
--nameHuman-readable job name
--cronCron expression (5 fields: min hour dom mon dow)
--everyInterval in milliseconds
--atISO 8601 timestamp for one-time jobs
--tzTimezone for cron expressions (e.g., America/Los_Angeles)
--sessionisolated (fresh context) or main (with history)
--messageAgent turn message (for isolated sessions)
--system-eventSystem event text (for main session)
--announceSend output to the active channel
--delete-after-runRemove the job after it runs once
--wakeWake mode: now, next-heartbeat

openclaw cron disable Command

Pause a job without deleting it. The job keeps its config and run history.

bash

# 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

bash

# 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

CommandWhat it does
openclaw cron statusShow scheduler status
openclaw cron listList all jobs
openclaw cron addCreate 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:

json

{
  "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:

  1. CLI commands (openclaw cron add, openclaw cron edit) for creating and managing individual jobs
  2. 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:

bash

openclaw gateway restart

Gateway-level cron settings in ~/.openclaw/config/config.json:

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.

json

{
  "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.

json

{
  "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.

json

{
  "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

bash

# 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.

Fresh context every run. No conversation history. The agent only knows what's in the job payload and workspace files.

json

{
  "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.

json

{
  "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)

json

{
  "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

json

{
  "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)

json

{
  "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

json

{
  "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:

  1. Check it exists: openclaw cron list or inspect ~/.openclaw/cron/jobs.json
  2. Check it's enabled: look for "enabled": true
  3. Check the schedule: cron expressions use your host's local timezone. On a VPS, that's often UTC. Add an explicit tz field if unsure.
  4. Check run history: openclaw cron runs --id <jobId> to see if it ran and what happened
  5. Check the logs: openclaw gateway logs or ~/.openclaw/logs/

Job runs but produces no output:

  1. Test the payload manually first. Paste the message text into chat and see if it works interactively.
  2. Check session targeting. If you used isolated but the task needs conversation context, it won't have it.
  3. Check delivery configuration. The job might run but send output to the wrong channel.

Job runs but fails:

  1. Check logs for error details
  2. 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.
  3. 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:

  1. Check frequency. 60000 ms is 1 minute, not 1 hour. A job that costs $0.02 per run at 1-minute intervals is $28.80/day.
  2. Check model routing. Jobs default to your configured model. Use a cheaper model for simple tasks if your setup supports model overrides.

Common Mistakes

MistakeWhat HappensFix
Wrong interval units$0.02/run x every minute = $28.80/dayDouble-check ms values against the table above
No timezone on a VPSCron uses host timezone (often UTC on VPS)Add "tz": "America/Your_Timezone" explicitly
Vague payloadAgent interprets differently each runWrite specific, actionable instructions
Testing in main, running in isolatedWorks in chat, fails as cron jobTest the exact payload in an isolated session first
Too many jobs at the same timeResource contention, slow executionStagger by 5 minutes: 7:00, 7:05, 7:10
Not monitoring costsSurprise bill at end of monthSet 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.



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
Did I get something wrong? Or have any other feedback? Let me know here.

More from Stack Junkie.

Get new articles by email.

More guides in The OpenClaw Handbook