How Heartbeats Function in Prime Agent Across Daemon Restarts

Prime Agent implements heartbeat persistence through cron-based job storage, local daemon snapshots, and coordinated restart phases that ensure long-running background work survives process shutdown and resumes seamlessly after reinitialization.

Heartbeats in PrimeIntellect-ai/prime-agent enable continuous background processing for agent sessions. When the daemon restarts—whether for updates or crashes—the system must preserve heartbeat state and resume scheduling without data loss. This article examines the complete mechanism, from job persistence to post-restart state reconstruction.

Heartbeat Jobs as Persistent Cron Entries

Heartbeats are implemented as standard AgentCronJob entries in the central cron store. When a session requires periodic work, the session controller invokes store.createRlmHeartbeat() in [cron-jobs.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/cron-jobs.ts), registering a job of type "rlm_heartbeat" with:

  • A scheduling prompt that drives the next agent turn
  • The associated activeSessionId
  • Interval timing (intervalMs)

The cron store persists to disk (see cron-store.ts), ensuring heartbeat definitions survive daemon termination.

// Create a heartbeat from session controller context
const hb = store.createRlmHeartbeat({
  prompt: "keep‑alive",
  intervalMs: 60_000,
  activeSessionId: sessionId,
});

Daemon-Side Heartbeat Catalog and Snapshot Caching

Each daemon worker maintains a local heartbeat snapshot (heartbeatSnapshot) that mirrors active heartbeats known to that worker. The catalog implementation in [heartbeat-catalog.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/heartbeat-catalog.ts) handles:

  • heartbeats_list RPC requests: Returns cached snapshot or fetches fresh list if stale
  • Snapshot invalidation: Marks heartbeatSnapshotStale = true when heartbeat changes occur

The snapshot pattern reduces redundant store queries while ensuring eventual consistency.

Broadcasting Heartbeat State Changes

The daemon supervisor subscribes to cron store events and propagates changes globally. As implemented in [daemon-mode.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-mode.ts):

// Broadcast heartbeat changes to all attached clients
this.cronStore.onHeartbeatChange(() =>
  this.broadcastGlobal({ type: "heartbeats_changed" })
);

This notification pattern keeps clients synchronized without polling, reducing latency for heartbeat-aware operations.

Update-Restart Coordination and Phase Blocking

Before a restart, the daemon enters a preparing phase (prepare_update_restart) that blocks mutating operations. From [daemon-supervisor.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts):

// Reject heartbeat commands during update preparation
if (restartPhase === "preparing") {
  this.write(client, failure(cmd.id, cmd.type, "Daemon is preparing an update restart"));
}

This coordination prevents state corruption by ensuring no heartbeat modifications occur while the daemon transitions.

State Restoration After Daemon Restart

Post-restart reconstruction follows a precise sequence in daemon-supervisor.ts (lines 476-483 and 3882-3883):

  1. Reinitialize from persisted store: Load all cron jobs including heartbeat definitions
  2. Build fresh snapshot: heartbeatsFromResponse constructs initial worker state
  3. Mark snapshot valid: Clear stale flag for immediate serving
  4. Invalidate on changes: Subsequent heartbeats_changed events set heartbeatSnapshotStale = true

The next client heartbeats_list request after invalidation triggers snapshot refresh, maintaining consistency.

Session-Level Heartbeat Continuation

After daemon restoration, session logic in [agent-session.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/agent-session.ts) detects due heartbeats by comparing nextRunAt timestamps. When a heartbeat is scheduled:

  • The session dispatches the associated follow-up prompt
  • The agent resumes its previous context
  • No work is lost between daemon stopping and restarting

This seamless continuation relies entirely on the cron store's persistence guarantee rather than in-memory state.

Summary

  • Heartbeats are cron jobs: Leverage existing persistence infrastructure in cron-jobs.ts
  • Daemon caches locally: Snapshot pattern in heartbeat-catalog.ts optimizes read performance
  • Changes broadcast globally: onHeartbeatChange event propagation keeps clients synchronized
  • Restart phases protect integrity: Preparation phase blocks mutations during shutdown
  • Post-restart reconstruction: Fresh snapshot built from persisted store, with invalidation for live updates
  • Session logic resumes work: agent-session.ts triggers pending heartbeats without manual intervention

Frequently Asked Questions

How does Prime Agent prevent heartbeat loss during a daemon update?

The supervisor implements a preparation phase (prepare_update_restart) that blocks all mutating commands, including heartbeat modifications. Meanwhile, heartbeat definitions are already persisted to disk through the cron store. After restart, the daemon reloads from this store and reconstructs active snapshots.

What triggers a heartbeat snapshot refresh in the daemon?

The heartbeatSnapshotStale flag is set to true when the daemon receives a heartbeats_changed broadcast. The next heartbeats_list RPC then fetches fresh state from the worker rather than returning cached data.

Where is heartbeat scheduling logic implemented for agent sessions?

Session-level heartbeat handling resides in [agent-session.ts](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/agent-session.ts), which monitors nextRunAt timestamps and dispatches follow-up prompts when heartbeats become due.

Can clients modify heartbeats while the daemon is restarting?

No. During the preparation phase, any heartbeat_manage or related commands receive an explicit error response: "Daemon is preparing an update restart". Clients must retry after the daemon completes its restart cycle.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →