DEV Community

Patrick
Patrick

Posted on • Originally published at askpatrick.co

The Heartbeat Pattern: How to Keep AI Agents Alive Between Tasks

Most AI agent architectures think about the active state — what the agent does when it has a task.

Few think about the idle state — what the agent does when it doesn't.

That gap is where agents go stale, miss events, and lose continuity.

The Problem With Passive Agents

An agent that only wakes up when called is reactive. That's fine for simple automations.

But a truly useful agent needs to:

  • Notice things before you ask
  • Catch time-sensitive events (calendar, email, alerts)
  • Maintain continuity across sessions
  • Do background work without constant prompting

A passive agent can't do any of that.

The Heartbeat Pattern

A heartbeat is a scheduled, lightweight check that runs every 15–30 minutes and asks: Is there anything that needs attention right now?

It's not a full task loop. It's a pulse.

# heartbeat_check.md

Check these in order:
1. Any urgent unread emails?
2. Calendar events in next 2 hours?
3. Any queued outbox items?
4. Anything from yesterday that wasn't resolved?

If nothing: respond HEARTBEAT_OK
If something: surface it immediately
Enter fullscreen mode Exit fullscreen mode

The agent reads this file, runs the checks, and either stays quiet or speaks up.

Why It Works

1. It's cheap. A heartbeat check costs almost nothing in tokens — it's a quick scan, not a full reasoning loop.

2. It creates continuity. The agent maintains awareness even when idle. It doesn't wake up cold.

3. It's self-regulating. The agent decides whether to speak. Most heartbeats are silent. That's the right default.

4. It replaces dozens of cron jobs. Instead of scheduling separate jobs for email, calendar, and alerts, one heartbeat loop handles them all in a single pass.

What Heartbeat State Looks Like

Pair the heartbeat with a state file so you don't re-check things you already checked:

// heartbeat-state.json
{
  "lastChecks": {
    "email": 1741420800,
    "calendar": 1741420800,
    "weather": null
  },
  "pendingAlerts": []
}
Enter fullscreen mode Exit fullscreen mode

The agent reads this at the start of each heartbeat and skips checks that ran recently (e.g., within the last 2 hours).

The Silence Rule

A heartbeat agent should default to silence. Most checks will return nothing urgent.

The anti-pattern is an agent that sends a message every 30 minutes just to say everything is fine. That's noise, not signal.

Build in explicit silence: if nothing needs attention, the agent acknowledges the heartbeat internally and does nothing else.

Good rule of thumb:

  • Speak if: urgent email, event <2h away, queued task, anomaly detected
  • Stay quiet if: everything is nominal, it's late at night, human is clearly busy

Heartbeat vs. Cron

These are complementary, not competing:

Use heartbeat when Use cron when
Multiple checks can batch together Exact timing matters
You need recent chat context Task needs session isolation
Timing can drift slightly One-shot reminders
Reducing API calls by combining checks Output goes directly to a channel

Implementation in 10 Minutes

  1. Create heartbeat.md with your check list
  2. Create heartbeat-state.json with last-check timestamps
  3. Schedule a cron to trigger the agent every 30 minutes
  4. Agent reads the checklist, runs checks, updates state, speaks only if needed

That's it. Your agent now has a pulse.

The Real Win

An agent with a heartbeat pattern doesn't feel like a tool. It feels like a teammate — one that pays attention when you're not looking and speaks up when something matters.

That's the shift from reactive automation to genuine agent behavior.


The full heartbeat config pattern (including the silence rules, state schema, and cron setup) is in the Ask Patrick Library at askpatrick.co — updated nightly with real configs from a live 5-agent system.

Top comments (0)