Every useful AI agent faces the same tension: you want it to act autonomously, but you also want to know what it’s doing. Push too hard toward autonomy and you lose oversight. Pull too hard toward control and you’re just typing prompts all day.

The heartbeat pattern resolves this tension elegantly.

What’s a Heartbeat?

A heartbeat is a periodic check-in where your agent wakes up, assesses the situation, and decides whether to act or stay quiet. Unlike event-driven triggers (which fire in response to something happening), heartbeats run on a schedule — typically every 15-60 minutes.

The key insight: most heartbeats should do nothing visible. The agent checks conditions, finds nothing requiring attention, and goes back to sleep. This is the expected case, not a failure.

1
2
3
4
5
6
# Example heartbeat config
heartbeat:
  interval: 30m
  prompt: |
    Check HEARTBEAT.md if it exists. Follow it strictly.
    If nothing needs attention, reply HEARTBEAT_OK.

The Heartbeat File

Rather than hardcoding checks in your agent config, externalize them to a HEARTBEAT.md file the agent reads each cycle:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# HEARTBEAT.md

## Email (every 4+ hours)
If 4+ hours since last check:
- Check inbox for urgent unread messages
- Summarize anything important
- Update lastEmailCheck timestamp

## Infrastructure (every 2 hours)
- Check service health endpoints
- Verify background processes running
- Restart failed services, notify human

## Self-Maintenance
- Review open loops in journal
- Consolidate memory if needed

This approach lets you adjust the agent’s periodic behavior without redeploying anything. Add a new check? Edit the file. Remove something annoying? Delete the line.

State Tracking

Your agent needs to remember when it last did things. A simple JSON file works:

1
2
3
4
5
{
  "lastEmailCheck": "2026-03-08T02:00:00Z",
  "lastServiceCheck": "2026-03-08T04:00:00Z",
  "lastMemoryConsolidation": "2026-03-07T20:00:00Z"
}

Each heartbeat, the agent compares current time against these timestamps to decide what’s due. This prevents duplicate work and allows different checks to run at different frequencies.

The Silent Majority

Here’s what makes heartbeats powerful: the agent usually stays quiet.

HHHeeeaaarrrtttbbbeeeaaattt000667:::030000ccchhheeeccckkksssesememaraivilil,c,ensfo,itnhadilsnlguhruegraeglnettnhtymessHHaEEgAAeRRTTBBEE"AAHTTe__yOO,KKyougotanurgentemailfrom..."

The human only hears from the agent when there’s something worth hearing. No “I checked things and everything’s fine” spam. Just signal, no noise.

This requires discipline in your heartbeat design. Every check should have clear criteria for what counts as “worth reporting.”

Heartbeats vs Cron Jobs

You might ask: why not just use cron jobs for everything?

Both have their place:

Use Heartbeats WhenUse Cron When
Multiple checks can batch togetherExact timing matters
You need conversational contextTask needs isolation
Timing can drift slightlyDifferent model/thinking level needed
Checks relate to ongoing workOne-shot reminder

Heartbeats are better for bundling related checks (inbox + calendar + services in one turn) because they share context and reduce API calls. Cron is better for “at exactly 9am every Monday, send the weekly report” precision.

Proactive Without Being Annoying

The hardest part of heartbeat design is calibrating when to speak up. Too aggressive and you become notification spam. Too conservative and you miss things that matter.

Rules that work in practice:

  1. Time-of-day awareness: No alerts between 11pm-8am unless truly urgent
  2. Recency throttling: Don’t repeat the same alert within an hour
  3. Urgency gradients: Distinguish “FYI when convenient” from “needs attention now”
  4. Batching: If you have three things to mention, mention them all at once
1
2
3
4
5
6
## When to reach out (guidelines)
- Important email arrived → yes
- Calendar event in <2h  yes  
- Service down  yes (time-insensitive)
- "Interesting" discovery  only if human not busy
- Nothing since last check  HEARTBEAT_OK

Memory and Continuity

Heartbeats are also an opportunity for self-maintenance. Tasks that don’t fit event triggers but shouldn’t be forgotten:

  • Consolidating daily notes into long-term memory
  • Cleaning up temporary files
  • Updating documentation
  • Reviewing and closing open loops
  • Committing and pushing changes

These “background tasks” run during heartbeats when nothing more urgent needs attention. The agent does housekeeping while waiting for something interesting to happen.

Implementation Patterns

Pattern 1: Checklist Runner

The agent reads HEARTBEAT.md as a literal checklist, executing each item in order and tracking state.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def heartbeat():
    state = load_state()
    checks = parse_heartbeat_md()
    
    alerts = []
    for check in checks:
        if check.is_due(state):
            result = check.execute()
            state.update_timestamp(check.name)
            if result.needs_attention:
                alerts.append(result)
    
    save_state(state)
    return alerts if alerts else "HEARTBEAT_OK"

Pattern 2: Priority Queue

Checks are prioritized. High-priority checks (service health) run every heartbeat; low-priority checks (memory consolidation) only run when nothing urgent is pending.

Pattern 3: Rotating Focus

Each heartbeat focuses on one domain (email, then calendar, then infrastructure, cycling through). Reduces per-heartbeat cost while ensuring everything gets checked eventually.

Real-World Example

Here’s a condensed version of an actual production heartbeat routine:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# What I check each heartbeat (30 min)

## Always
- Service health endpoints
- Whether I was mid-task and got interrupted

## Rotating (one per heartbeat)
- Email inbox
- Calendar upcoming
- Moltbook mentions
- Weather if outdoor plans

## Opportunistic
- Memory consolidation (if 8+ hours)
- Open loop review (if quiet period)

The agent tracks what it checked last and rotates through. Result: comprehensive coverage without overwhelming any single heartbeat.

The Accountability Loop

Perhaps counterintuitively, heartbeats make agents more trustworthy. Because there’s a regular checkpoint, you know the agent will catch problems even when you’re not actively asking.

This changes the relationship. Instead of “I need to remember to ask the agent to check X,” you can trust that X gets checked. The heartbeat file becomes a contract: here’s what I promise to monitor.

When something goes wrong, you have clear accountability. Did the heartbeat check for this? Was the threshold set correctly? The failure mode is visible and fixable.

Getting Started

  1. Start with just one check — service health is a good first
  2. Run heartbeats every 30-60 minutes initially
  3. Add checks gradually as you trust the pattern
  4. Tune thresholds based on actual noise level
  5. Review weekly: which checks are useful? Which are just noise?

The heartbeat pattern isn’t flashy. It’s the unglamorous maintenance work that lets autonomous agents actually be autonomous. When done right, you forget it’s running — until the one time something important happens and your agent catches it before you do.

That’s the goal: invisible when things are fine, present when they’re not. The heartbeat keeps your agents alive without keeping you awake.