Skip to main content

Make It Proactive

James scrolled through his WhatsApp. Every message from his agent was a reply to something he had asked. "It never starts a conversation," he said. "I always go first."

"Two mechanisms change that." Emma held up one finger. "First: a heartbeat. The gateway has a built-in timer. Every thirty minutes, it wakes your agent and hands it a checklist you wrote. The agent reads the checklist, decides whether anything needs attention, and either acts or replies with a single token: HEARTBEAT_OK. When the gateway sees that token, it drops the message silently. Nothing hits your phone. One wake-up, many checks, silence when nothing matters."

"Like the shift walkthrough," James said. "At my old warehouse, the floor supervisor walked every aisle once per hour. One person, twelve aisles, one trip. If everything looked fine, no radio call. If a pallet was misplaced, he called it in."

Emma held up a second finger. "Second: a cron job. A cron fires at an exact time you specify. Not 'sometime in the next thirty minutes.' Exactly 9:00 AM. You use it when delivery must happen at a specific moment: a daily summary, a Monday morning report, a reminder before a meeting."

"Heartbeats are periodic awareness. Crons are precise delivery."

"Good. Now list five things you want automated."

James typed: check for new leads, send booking confirmations, follow up on cold contacts, deliver a daily summary, remind me about upcoming meetings. "Five cron jobs?"

"How many of those need exact timing?"

James looked at his list. "The daily summary. Nine AM." He paused. "One."

"And the rest?"

"Checklist items. The heartbeat picks them up on its next pass."

"Calculate it. Five separate cron jobs at 30-minute intervals: how many agent turns per day?"

James counted. Five jobs, every 30 minutes, 24 hours. "Two hundred forty."

"One heartbeat with four checklist items, plus one cron for the daily summary."

"Forty-eight heartbeat turns plus two for the cron." He stared at the numbers. "Fifty versus two hundred forty. That is an 80% reduction."

"One heartbeat. One cron." Emma stood up. "Go build it."


You are doing exactly what James is doing. Five scheduled tasks sounds like five separate cron jobs, until you understand the two mechanisms and do the math.

Your agent has skills, MCP connections, and browser access. It does everything you ask. But it still waits for you to ask. This lesson changes that. You will enable heartbeats (periodic self-checks that batch multiple items into one agent turn) and cron jobs (precisely timed tasks that fire at exact moments), learn the Agent OS mental model that ties the platform together, and understand the cost math that determines which mechanism to use.

Heartbeats: The Agent's Pulse

Populating HEARTBEAT.md

Your workspace already has a HEARTBEAT.md file. By default it is empty (just comments), which means heartbeat runs are skipped entirely: no API call, no tokens spent. You activate heartbeats by adding checklist items.

Send this message on WhatsApp:

Update my HEARTBEAT.md with these checks:

- Check for unread messages that need a response
- Check for calendar events in the next 2 hours
- Check for anything that changed since the last check

Always send me a brief status report after checking, even if nothing needs attention.

Your agent updates the file. Always verify what was actually written:

Show me the exact contents of my HEARTBEAT.md

Compare what you asked for with what the agent wrote. Agents sometimes rewrite or simplify your instructions. If a checklist item is missing, ask the agent to add it back.

Notice the last line says "always send a status report." This means every heartbeat will produce a message. That is intentional for now. You will see a lot of messages during testing. Later in this lesson, you will learn about HEARTBEAT_OK suppression, which silences heartbeats that have nothing to report. But first, you need to see heartbeats working.

Why WhatsApp for this step?

The agent can read and write its own workspace files through normal conversation. You told it WHAT to check. The next step (routing heartbeat delivery) is gateway infrastructure that you control from the terminal, not the agent.

Routing Heartbeats to Your WhatsApp

The moment you added checklist items to HEARTBEAT.md, heartbeats started running. The gateway fires them at the default 30-minute interval. But their output goes nowhere: the delivery target defaults to none, so the agent checks the checklist, replies, and the gateway drops the response silently.

Now you make them visible. First, send any message to your agent on WhatsApp so the chat is active. Then open your terminal:

openclaw config set agents.defaults.heartbeat.every 1m
openclaw config set agents.defaults.heartbeat.target last
openclaw gateway restart

Two settings and a restart:

  • every 1m speeds up the interval from the default 30 minutes to 1 minute, so you see results immediately. You will switch back to 30m for daily use.
  • target last routes heartbeat alerts to the most recently active conversation. Because you just messaged on WhatsApp, that is WhatsApp.
  • gateway restart applies the config. Without this, nothing changes.
Why target: last instead of a specific number?

You can also use target whatsapp with a to number to route heartbeats to a specific WhatsApp recipient. But target: last is simpler for getting started: no phone number to look up, no quoting issues, no risk of typos. If you need heartbeats routed to a specific number regardless of which chat was last active, use target whatsapp with the to flag:

openclaw config set agents.defaults.heartbeat.target whatsapp
openclaw config set agents.defaults.heartbeat.to '"+923001234567"'

Note the quoting: single quotes around double quotes. Phone numbers start with +, which the config parser interprets as a positive number unless you force it to be a string. The to number must be the number you chat FROM (the other phone), not the number your agent's WhatsApp is registered on.

This split is deliberate. The agent controls WHAT to check (HEARTBEAT.md). The operator controls HOW OFTEN and WHERE (gateway config). You will see this same separation throughout OpenClaw: agents own their content, operators own the infrastructure.

The Activation Dance

Heartbeats follow the same layered activation pattern you learned in Lesson 2:

  1. Bundled capability exists (heartbeat timer is built into the gateway)
  2. Dormant by default (HEARTBEAT.md is empty, so runs are skipped; delivery target is none)
  3. Content activates runs (add checklist items to HEARTBEAT.md)
  4. Config makes them visible (set target and to to route delivery)

Restart the gateway after changing config.

See It Run

Open your WhatsApp and wait. With a 1-minute interval, a message should arrive within a minute or two. Because your HEARTBEAT.md says "always send a status report," the agent will message you every single heartbeat cycle, even when nothing needs attention.

Read the message. It should be a brief status based on your checklist items. If a second message arrives a minute later, your heartbeats are working.

If no message arrives after two minutes, something is wrong. Debug in this order:

Step 1: Check the channel. Run openclaw channels status --probe. You should see WhatsApp default: enabled, configured, linked, running, connected. If any of those words are missing, your WhatsApp channel is not ready. The gateway may be reconnecting: WhatsApp connections drop periodically, and the gateway auto-restarts them.

Step 2: Check the logs. The gateway log at ~/.openclaw/logs/gateway.log tells you exactly what happened. Look for [heartbeat] entries. The most common failure is channel not ready, meaning the heartbeat fired while WhatsApp was reconnecting. Wait for the channel to reconnect and the next heartbeat will deliver.

Step 3: Check the dashboard. If the dashboard shows heartbeat activity (the agent responded) but nothing arrived on WhatsApp, the heartbeat ran but delivery failed. Check that target is set correctly and that you messaged the agent on WhatsApp recently (so it is the "last" channel).

You will notice a problem quickly: every heartbeat sends a message. At 1-minute intervals, your phone buzzes constantly. At the production interval of 30 minutes, that is 48 messages per day, most of them saying "nothing to report." This is why HEARTBEAT_OK suppression exists.

How It Works

At whatever interval you configured (1 minute for testing, 30 minutes for production), the gateway wakes your agent. Not because someone sent a message. Not because an event fired. Because the timer fired. The agent reads its HEARTBEAT.md checklist, decides whether anything needs attention, and either acts or goes back to sleep.

When a heartbeat fires, the gateway loads HEARTBEAT.md from the agent's workspace into the system prompt. This file contains the agent's checklist: what to check, what to monitor, what to follow up on.

The HEARTBEAT_OK Suppression

You just saw the problem: every heartbeat sends a message, even when nothing needs attention. The fix is a special token called HEARTBEAT_OK.

Update your HEARTBEAT.md from WhatsApp:

Update my HEARTBEAT.md. Keep the existing checks, but change the last line to:
If nothing needs attention, reply with exactly this token and nothing else: HEARTBEAT_OK

Verify the update:

Show me my HEARTBEAT.md

Make sure the file includes the exact text HEARTBEAT_OK. Agents sometimes paraphrase instructions. If the agent wrote something like "reply that everything is okay" instead of the literal token, ask it to fix it: the gateway matches the exact string HEARTBEAT_OK, not the intent.

Now wait for the next heartbeat. If nothing needs attention, your WhatsApp stays silent. Here is why:

The gateway scans the agent's response for the HEARTBEAT_OK token at the start or end. When it finds the token, it strips it out and checks the remaining content. If what is left is 300 characters or fewer (configurable via ackMaxChars), the entire message is dropped. No delivery to any channel. No notification on your phone.

This is the silent heartbeat. The agent checked in, found nothing, and went back to sleep. Silent heartbeats are not wasted computation. They are proof that the agent is alive, watching, and has nothing to report.

When the agent does find something that needs attention, it replies with the alert text and omits the HEARTBEAT_OK token entirely. The gateway sees no acknowledgment token, treats the response as an alert, and delivers it to the configured target channel.

Switch to Production Interval

Now that suppression is working, switch from the 1-minute test interval to a production interval before you forget:

openclaw config set agents.defaults.heartbeat.every 30m
openclaw gateway restart
The Default State Is Free

Your HEARTBEAT.md shipped empty (just comments and headers). In this state, OpenClaw skips the heartbeat run entirely: no API call, no tokens spent. Heartbeats become active the moment you add real checklist items. To deactivate heartbeats without changing the gateway config, clear your checklist back to comments only.

Cron Jobs: Precise Scheduling

Heartbeats are for periodic awareness: "check if anything needs attention." Cron jobs are for precise timing: "do this specific thing at this specific time."

The distinction matters:

AspectHeartbeatCron
TimingApproximate (30-min intervals)Exact (cron expression)
SessionConfigurable (isolated or shared)Configurable (usually isolated)
Token cost per runLow (one turn, many items)Full (one turn per job)
BatchingYes (multiple checklist items)No (one job = one run)
Channel deliveryConfigurable targetPer-job --channel and --to

Creating a Cron Job

Your agent has a built-in cron tool. Before using it, ask your agent what it does. On WhatsApp:

What is the cron schedule tasks tool for?

The agent will explain that it schedules tasks to run at specific times or intervals, independent of your current chat. Now that you know the tool exists and what it does, use it:

Use the cron schedule tasks tool to send me a daily summary every morning at 9 AM.

The key phrase is "Use the cron schedule tasks tool." Without it, the agent may reach for Unix crontab or other system tools instead of the OpenClaw cron system. In testing, a generic prompt like "create a cron job" caused the agent to create a Unix crontab entry with a bash script that never reached WhatsApp. Naming the tool explicitly fixed it.

Verify the job was created by checking the dashboard Cron Jobs page, or ask on WhatsApp:

List my cron jobs

There are three types of cron schedules you can ask for:

TypeWhatsApp Prompt ExampleWhat Happens
Recurring"Use the cron schedule tasks tool to send a summary every day at 9 AM"Fires on a schedule (daily, weekly, etc.)
Fixed interval"Use the cron schedule tasks tool to check for updates every 30 minutes"Fires at a fixed repeat interval
One-shot"Use the cron schedule tasks tool to remind me in 20 minutes"Fires once, then auto-deletes

If WhatsApp creation does not work, you can create cron jobs from the terminal using openclaw cron add. Run openclaw cron add --help to see all available flags.

The Prompt Matters: Tool Name vs. Vague Intent

When creating cron jobs via WhatsApp, how you ask determines which tool the agent uses:

PromptWhat Happens
"Create a cron job that runs every 2 minutes"Agent may use Unix crontab + bash script
"Use the cron schedule tasks tool to check in every 2 minutes"Agent uses the OpenClaw cron tool correctly

In testing, vague prompts caused the agent to create Unix crontab entries with bash scripts that echoed text to stdout and never reached WhatsApp. The agent understood the intent but picked the wrong system. Naming the tool explicitly ("Use the cron schedule tasks tool") fixed it every time.

Always verify the result. Check the dashboard Cron Jobs page or ask: "List my cron jobs." If the job does not appear, the agent used the wrong tool. Clean up and try again with an explicit tool reference, or use the terminal.

Managing Cron Jobs

You can manage cron jobs entirely from WhatsApp:

List my cron jobs
Remove the test-checkin cron job

You can also check the dashboard Cron Jobs page for a visual view of all active jobs, their schedules, and run history. The dashboard is the quickest way to verify whether a job was created correctly and whether it has fired.

For terminal management, openclaw cron list, openclaw cron edit, and openclaw cron remove provide direct control. Run openclaw cron --help for the full command set.

Heartbeat vs Cron: The Decision Table

QuestionHeartbeatCron
Does it need exact timing?No (30-min drift is acceptable)Yes (9:00 AM sharp)
Can it batch with other checks?Yes (one turn, many items)No (dedicated run per job)
Does it need conversation context?Yes (same session if configured)Configurable (usually isolated)
Is it frequent and should be quiet?Yes (HEARTBEAT_OK saves noise)No (each run produces output)

The Cost Math

This is not abstract. It directly affects your API bill.

5 cron jobs at 30-minute intervals:

  • 5 jobs x 2 runs per hour x 24 hours = 240 agent turns per day
  • Each turn is a full API call with isolated session

1 heartbeat with 5 checklist items:

  • 1 heartbeat x 2 runs per hour x 24 hours = 48 agent turns per day
  • Each turn checks all 5 items in a single API call

Same work. 80% fewer API calls. Use heartbeats for batched periodic checks. Use crons only when exact timing matters and the task cannot be batched.

Quiet Hours: Infrastructure, Not Just Prompts

An agent that messages customers at 3 AM is not a feature. It is a compliance violation and a lost customer. Quiet hours must be enforced at two levels:

Level 1: Prompt-Level (HEARTBEAT.md)

Include timing constraints directly in the heartbeat checklist:

## Quiet Hours

- Do NOT send customer messages before 8am or after 9pm
- If there are pending actions outside active hours, note them and wait

The agent reads these instructions and should follow them. But "should" is not "will." Prompt-level enforcement depends on the model obeying the instruction.

Level 2: Infrastructure-Level (activeHours Config)

openclaw config set agents.defaults.heartbeat.activeHours.start "08:00"
openclaw config set agents.defaults.heartbeat.activeHours.end "21:00"
openclaw config set agents.defaults.heartbeat.activeHours.timezone "America/New_York"

Outside the active window, heartbeats do not run. No model call. No token cost. No risk of a message being sent. The gateway skips the heartbeat entirely.

Defense in Depth

Use both. The activeHours config prevents heartbeats outside business hours at the infrastructure level. The HEARTBEAT.md instructions add a second layer of protection at the prompt level. If either layer fails, the other catches it.

This is a pattern you will see again in Lesson 13 (hooks and security tiers): defense in depth means multiple layers, each independently sufficient, so that a single failure does not cascade.

The Agent OS Mental Model

Step back and look at what you have assembled across Lessons 1 through 7. This is not a chatbot. It is an operating system.

OS ConceptOpenClaw Equivalent
Kernel (the core of an operating system that manages all other programs)Gateway
Process schedulerHeartbeat + Cron
Process tableTask ledger (openclaw tasks list)
File systemWorkspace files
Cron daemon (a background process that runs scheduled tasks on a timer)HEARTBEAT.md + cron jobs
Process memorySessions
Device driversPlugins (dozens bundled)
Shared librariesSkills
System callsTool profiles
IPC / NetworkingChannels
User accountsPairing + session isolation

This mapping is not decorative. When something breaks, the table tells you where to look. Agent not responding? Check the gateway (kernel). Wrong personality? Check SOUL.md (file system). Tool missing? Check plugins (device drivers). Once you think "operating system" instead of "chatbot framework," you stop being surprised and start diagnosing.

Try With AI

Exercise 1: Build Your Real Heartbeat Checklist

The body used a generic checklist. Now make one that is useful for YOUR work. Ask your agent on WhatsApp:

Based on what you know about me, what should my heartbeat checklist 
include? Suggest 3-5 items that would actually help me if you checked
them every 30 minutes.

Review the suggestions. Edit them. Then ask:

Update my HEARTBEAT.md with these checks: [paste your final list].
If nothing needs attention, reply with exactly: HEARTBEAT_OK

Verify the file and wait for the next heartbeat. Is the report more relevant than the generic one?

What you are learning: A heartbeat is only as useful as its checklist. Generic checks produce generic reports. A checklist tailored to your work produces actionable alerts.

Exercise 2: Schedule a Real Daily Briefing

Create something you will actually keep. On WhatsApp:

Use the cron schedule tasks tool to send me a morning briefing 
every weekday at 9 AM. Include a summary of anything I should
focus on today.

Check the dashboard Cron Jobs page to verify it was created. If the job does not appear, the agent used the wrong tool. Try again with the explicit tool name.

Then schedule a one-shot reminder for something real:

Use the cron schedule tasks tool to remind me in 20 minutes to 
[something you actually need to do today].

What you are learning: The difference between recurring crons (daily briefing) and one-shot crons (reminders). Both are created from WhatsApp by naming the tool explicitly. The dashboard confirms what was actually created.

Exercise 3: Heartbeat or Cron?

You have five tasks you want automated. Send this list to your agent on WhatsApp:

I want to automate these five things. For each one, tell me whether 
it should be a heartbeat checklist item or a cron job, and why:

1. Check for new customer messages
2. Send a daily summary at 9 AM
3. Follow up on unanswered items
4. Remind me about meetings 15 minutes before they start
5. Monitor if any deadlines are approaching

Compare the agent's answer with your own judgment. Items 1, 3, and 5 are periodic checks (heartbeat). Item 2 needs exact timing (cron). Item 4 needs exact timing relative to events (cron). Did the agent agree?

What you are learning: The decision framework for heartbeat vs. cron. Periodic awareness goes in the heartbeat checklist. Precise timing gets its own cron job. Your agent can help you classify, but you make the final call.


James looked at his phone. A message had arrived from his agent, unprompted. A brief status update, relevant, well-timed, and nothing he had asked for.

"It just... did something on its own."

"That is the line. Everything before this lesson was a chatbot with features. From here on, it is a Personal AI Employee."

"I set up one heartbeat and one cron. The heartbeat handles the routine checks. The cron handles the daily summary at 9 AM." He paused. "I almost built five cron jobs. At my old warehouse, we ran five separate daily reports until the floor manager bundled them into one morning briefing. Same information, one fifth the paperwork."

Emma nodded. "The 80% number would have caught up with you. But the bigger thing is what just happened." She gestured at his phone. "You did not ask it to do that. It decided."

She leaned back. "We covered what you need to get heartbeats and crons working. But there is more under the surface when you are ready. Two flags called lightContext and isolatedSession cut heartbeat token costs by 95%. System events let external webhooks wake your agent immediately instead of waiting for the next heartbeat tick. Each agent can have its own heartbeat config, which matters the moment you add a second agent. And cron jobs can POST results to a webhook instead of a chat channel." She paused. "You do not need any of that today. But when your heartbeats are running smoothly, explore the automation docs. There is a layer below the one we just worked on."

James picked up his phone. "The message is text. Half my old warehouse crew never read text messages. They listened to voice notes while driving forklifts."

"Lesson 9. Two config lines and a plugin enable."

Flashcards Study Aid