Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Master OpenClaw's timing systems. Use for scheduling reliable reminders, setting up periodic maintenance (janitor jobs), and understanding when to use Cron vs Heartbeat for time-sensitive tasks.
.claude/skills/sundial-org-cron-mastery/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 30% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 100% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 6% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -7% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -28% | 0% |
Rule #1: Heartbeats drift. Cron is precise.
This skill provides the definitive guide for managing time in OpenClaw. It solves the "I missed my reminder" problem by enforcing a strict separation between casual checks (heartbeat) and hard schedules (cron).
| System | Behavior | Best For | Risk | | :--- | :--- | :--- | :--- | | Heartbeat | "I'll check in when I can" (e.g., every 30-60m) | Email checks, casual news summaries, low-priority polling. | Drift: A "remind me in 10m" task will fail if the heartbeat is 30m. | | Cron | "I will run at exactly X time" | Reminders ("in 5 mins"), daily reports, system maintenance. | Clutter: Creates one-off jobs that need cleanup. |
Never use act:wait or internal loops for long delays (>1 min). Use cron:add with a one-shot at schedule.
Use this payload structure for "remind me in X minutes" tasks:
json{ "name": "Remind: Drink Water", "schedule": { "kind": "at", "atMs": <CURRENT_MS + DELAY_MS> }, "payload": { "kind": "agentTurn", "message": "⏰ Reminder: Drink water!", "deliver": true }, "sessionTarget": "isolated", "wakeMode": "next-heartbeat" }
Note: Even with wakeMode: "next-heartbeat", the cron system forces an event injection at atMs. Use mode: "now" in the cron:wake tool if you need to force an immediate wake outside of a job payload.
One-shot cron jobs (kind: at) disable themselves after running but stay in the list as "ghosts" (enabled: false, lastStatus: ok). To prevent clutter, install the Daily Janitor.
cron:list (includeDisabled: true)Daily Cron CleanupeveryMs: 86400000)> "Time for the 24-hour cron sweep. List all cron jobs including disabled ones. If you find any jobs that are enabled: false and have lastStatus: ok (finished one-shots), delete them to keep the list clean. Do not delete active recurring jobs. Log what you deleted."
For cron to work, the agent must know its time.
MEMORY.md.Timezone: Cairo (GMT+2)Problem: If you say "I'll wait 30 seconds" and end your turn, you go to sleep. You cannot wake up without an event. Solution: If you need to "wait" across turns, you MUST schedule a Cron job.
act:wait).wakeMode: "now".Example Payload for "Checking back in 30s":
json{ "schedule": { "kind": "at", "atMs": <NOW + 30000> }, "payload": { "kind": "agentTurn", "message": "⏱️ 30s check-in. Report status." }, "wakeMode": "now" }
cron:list. If the job exists but didn't fire, check the system clock vs atMs.Other measured skills in the registry, with their headline benchmark lift.