The OpenClaw cron system is one of those features builders overlook until they need it — then they wonder how they shipped anything without it. Schedule a daily briefing. Fire a weekly report. Run a monitoring loop every fifteen minutes. All without touching system cron, without writing a shell wrapper, without keeping a separate process alive.
Here's what you actually need to understand about how it works before you build on top of it.
How the OpenClaw Scheduler Works
The cron engine lives inside the gateway process. When the gateway starts, it loads all registered cron jobs from its data store and initializes a scheduler. At each trigger point, the scheduler constructs a delivery event — a channel ID plus a message or skill invocation — and routes it through the normal message pipeline.
This is the key insight: scheduled tasks go through the same pipeline as user messages. They're subject to the same LLM configuration, the same memory context, the same skill availability. There's no "background mode" with reduced capabilities. A cron-triggered message is just a message from a timer rather than a user.
The data store is local to the gateway — typically a SQLite or embedded key-value file depending on your gateway version. As of early 2025, there's no cloud sync or multi-gateway job sharing. Jobs you add to one gateway instance are owned by that instance.
The Cron Subcommands
The openclaw cron namespace has five subcommands. You'll use all five once your setup scales beyond a handful of jobs.
# Add a new scheduled job
openclaw cron add --schedule "0 9 * * *" --channel CHANNEL_ID --message "Daily report" --name "daily-report"
# List all jobs
openclaw cron list
# Disable a job (pauses without deleting)
openclaw cron disable JOB_ID
# Re-enable a paused job
openclaw cron enable JOB_ID
# Remove a job permanently
openclaw cron remove JOB_ID
openclaw cron list is your primary management view. The output format looks like this:
ID NAME SCHEDULE CHANNEL STATUS
abc123def456 daily-report 0 9 * * * ch-telegram-1 enabled
789xyz001234 weekly-summary 0 8 * * 1 ch-slack-main enabled
555qqq888rrr dev-monitor */15 * * * * ch-dev-alerts disabled
Copy the ID column when you need to disable or remove a specific job. The NAME column is why you always set --name — it's the only human-readable reference you have in this list.
Real-World Use Cases
Here's what I've seen builders actually ship with the cron system:
Daily morning briefing
A message fires at 8 AM telling the agent to pull yesterday's metrics, summarize open issues, and list today's scheduled events. The agent reads from memory and external tools and delivers a formatted digest to Telegram or Slack.
openclaw cron add \
--schedule "0 8 * * 1-5" \
--channel your-channel-id \
--message "Generate my morning briefing: check yesterday's metrics, open tasks, and today's calendar" \
--name "morning-briefing-weekdays" \
--timezone "America/Chicago"
Hourly monitoring alert
A skill fires every hour to check service health endpoints. If something is down, it sends an alert to a dedicated channel. If everything is healthy, it logs silently to memory without sending a visible message.
Weekly review automation
Every Monday at 7 AM, the agent compiles a weekly summary from the past week's conversation history and memory, formats it, and posts to a team channel. Zero manual effort after the initial setup.
Managing Jobs at Scale
When you have more than five or six scheduled jobs, management discipline matters. Here's the system that works consistently:
- Always use --name. No exceptions. The name is your primary identifier in logs and list output.
- Use a naming convention. Something like
env-category-frequency:prod-reports-daily,prod-monitor-hourly. - Document jobs externally. Keep a simple markdown file listing every job's name, schedule, channel, and purpose. The gateway list doesn't store notes.
- Audit quarterly. Run
openclaw cron listand verify every job still has a valid channel and a current purpose. Stale jobs accumulate silently.
Reliability Patterns
Missed executions happen. The gateway goes down for maintenance, gets restarted for an update, or crashes unexpectedly. Here's how to design around that:
Make tasks idempotent. A task that can safely run twice produces the same result as one that ran once. "Generate and send today's summary" is not idempotent — it could send a duplicate. "Check if today's summary has been sent, and if not, send it" is idempotent.
Use memory as a checkpoint. Before running a scheduled action, have the agent check memory for evidence the task already ran today. This pattern handles both duplicate firing and missed-then-replayed scenarios.
Don't rely on sub-minute precision. The OpenClaw cron scheduler fires within a few seconds of the scheduled time. For tasks that need sub-minute precision, use an external trigger via the gateway API instead.
Common Mistakes
Using system cron to call openclaw cron
Some builders wrap the cron system in an outer system cron job. Don't. You end up with duplicate scheduling complexity and two layers to debug. Use OpenClaw cron directly and trust the gateway to manage it.
Not auditing for orphaned jobs
Channels get renamed, reconfigured, or deleted. Jobs targeting those channels continue firing and failing silently. Run openclaw cron list after any channel changes and clean up immediately.
Over-scheduling monitoring tasks
Running a monitoring check every minute sounds useful. In practice, every check is a message that the agent processes, which costs LLM tokens. Use the minimum frequency that meets your actual monitoring needs — usually every 15–30 minutes for most use cases.
Frequently Asked Questions
What is openclaw cron?
openclaw cron is the built-in scheduling subsystem of the OpenClaw gateway. It fires agent tasks on a recurring schedule using cron expressions — no external cron daemon, no system-level cron jobs. Everything runs inside the gateway process and persists across restarts.
How do I see all my scheduled cron jobs?
Run openclaw cron list. The output shows each job's ID, name, schedule expression, target channel, and enabled status. Use the ID from this list when you need to remove or update a specific job with openclaw cron remove [id].
Can I pause a cron job without deleting it?
Yes. Run openclaw cron disable [id] to pause a job. It stays in your list but won't fire until you run openclaw cron enable [id]. This is useful for holiday freezes or temporary maintenance windows without losing your schedule configuration.
What happens to skipped cron executions?
Skipped executions are not replayed. If the gateway is down when a job was scheduled to fire, that occurrence is lost. The scheduler picks up at the next scheduled time. For critical tasks, design the agent message to be idempotent so catching the next occurrence is sufficient.
Can I run multiple cron jobs targeting the same channel?
Yes. Multiple jobs can target the same channel. Each fires independently on its own schedule. If two jobs fire simultaneously, the gateway queues both and delivers them sequentially. There is no rate limiting between cron-triggered messages by default.
Does cron support environment-specific schedules?
Not natively. The typical pattern is to maintain separate job configurations per environment and use the --enabled false flag to create jobs in a paused state during setup. Enable them explicitly after verifying the environment is ready. Jobs reference channel IDs which differ between environments anyway.