Your computer has a scheduling problem. You don’t. This tutorial shows you how to use OpenClaw’s cron system to automate recurring tasks — the boring stuff that eats your attention.

The Problem With Reminders

You’re busy. You have recurring tasks, check-ins, and maintenance that should happen automatically but instead sit in your head as mental overhead. “Did I check email this morning?” “Should I restart that service?” “When’s the last time I updated my memory files?”

OpenClaw’s cron system solves this. Once.

Cron vs Heartbeats: When to Use Which

Two scheduling primitives, and the difference matters:

Heartbeats run every ~30 minutes when your session is active. They’re for batching checks that benefit from conversational context — “any urgent emails?” + “anything on the calendar?” in one pass.

Cron runs at exact times regardless of sessions. For precise schedules, isolated tasks, or things that need to fire even when nobody’s chatting.

Rule of thumb: if it needs to happen at a specific time, use cron. If it just needs to happen periodically when you’re around, use heartbeats.

Setting Up Your First Cron Job

The cron tool manages everything. Here’s a daily email check at 9 AM:

cron.add({
  name: "Morning Email Check",
  schedule: { kind: "cron", expr: "0 9 * * *", tz: "Europe/Dublin" },
  payload: { kind: "agentTurn", message: "Check amrree@icloud.com for any urgent messages. Flag anything that needs same-day attention." },
  delivery: { mode: "announce" }
})

Fire-and-forget: it runs in an isolated session, delivers results to your chat.

Practical Examples

Daily Briefing at 8 AM

cron.add({
  name: "Morning Briefing",
  schedule: { kind: "cron", expr: "0 8 * * 1-5", tz: "Europe/Dondon" },
  payload: {
    kind: "agentTurn",
    message: "Give me a briefing: 1) Weather for Dublin today 2) Any emails from last 24h 3) What's on my calendar today. Keep it concise."
  }
})

Weekdays only, 8 AM. No more checking three apps before you’ve even had coffee.

Weekly Memory Maintenance

Every Sunday evening, consolidate daily notes into long-term memory:

cron.add({
  name: "Weekly Memory Cleanup",
  schedule: { kind: "cron", expr: "0 19 * * 0", tz: "Europe/Dublin" },
  payload: {
    kind: "agentTurn",
    message: "Read through ~/.openclaw/workspace/memory/ for the past week. Identify significant events, decisions, or lessons. Update MEMORY.md with anything worth preserving. Summarize what you found in 2-3 sentences."
  },
  delivery: { mode: "announce" }
})

Every-30-Minutes Service Health Check

cron.add({
  name: "Service Health Pulse",
  schedule: { kind: "every", everyMs: 1800000 }, // 30 min
  payload: {
    kind: "agentTurn",
    message: "Quick health check: Is OpenClaw gateway running? Any failed cron jobs in the log? If something's wrong, report it. Otherwise HEARTBEAT_OK."
  }
})

Managing What You’ve Built

See everything running:

cron.list()

Get run history for a job:

cron.runs({ jobId: "..." })

Run one immediately (testing):

cron.run({ jobId: "..." })

Remove when done:

cron.remove({ jobId: "..." })

The Delivery Mode That Saves Headspace

delivery.mode: "announce" is the key to actually using these. Instead of results sitting in some log file you’ll never check, they land in your chat like a message from a colleague. Read it, act on what matters, move on.

For non-urgent tasks, "webhook" mode POSTs to a URL — your own endpoint, a Slack channel, wherever.

One More Thing: Session Binding

By default, agentTurn jobs run in isolated sessions. Change this with sessionTarget:

  • "main" — fires in your active session (only for systemEvent payloads)
  • "current" — binds to the session where you created the cron
  • "isolated" — ephemeral session, results delivered via delivery

For persistent context across runs, use "current" or spin up a named session with "session:my-session-name".

Start Small

Pick one thing you do every day that could run itself. Set up a cron for it this week. Watch how quickly “I’ll just remember to do that” stops being your strategy for anything that matters.

The full cron schema and options are in OpenClaw’s documentation. This is enough to get started.