Bug
When multiple tickets are assigned to an agent in quick succession, each assignment fires a separate heartbeat wakeup with no debouncing or rate limiting.
Impact
We created ~90 tickets assigned to one agent over 30 minutes. This triggered 92 assignment wakeups on top of scheduled heartbeats. The agent ran 88 times in one hour (vs expected 1 per 2-hour interval). Each run consumed DB connections and API tokens. When the agent hit its LLM token limit, heartbeat_runs stayed in running status (zombie runs), driving server load to 4x per CPU and triggering load-protection cascades that paused all other agents.
Expected behavior
Assignment wakeups should be debounced: at most 1 wakeup per agent per 60 seconds, regardless of how many tickets are assigned in that window.
Related
Similar to issue #6414 (dependency checker fires every 30 seconds for blocked tickets). Both are scheduler events that fire per-ticket instead of being batched per-agent.
Additional issue: zombie heartbeat_runs
When a heartbeat fails (adapter error, token limit, process crash), the heartbeat_runs row stays in running status permanently. There is no timeout or cleanup. These zombie rows accumulate and each one triggers scheduler queries, creating a feedback loop with the dependency checker.
Environment
paperclipai@2026.517.0, embedded PostgreSQL, 16 agents.
Bug
When multiple tickets are assigned to an agent in quick succession, each assignment fires a separate heartbeat wakeup with no debouncing or rate limiting.
Impact
We created ~90 tickets assigned to one agent over 30 minutes. This triggered 92 assignment wakeups on top of scheduled heartbeats. The agent ran 88 times in one hour (vs expected 1 per 2-hour interval). Each run consumed DB connections and API tokens. When the agent hit its LLM token limit, heartbeat_runs stayed in running status (zombie runs), driving server load to 4x per CPU and triggering load-protection cascades that paused all other agents.
Expected behavior
Assignment wakeups should be debounced: at most 1 wakeup per agent per 60 seconds, regardless of how many tickets are assigned in that window.
Related
Similar to issue #6414 (dependency checker fires every 30 seconds for blocked tickets). Both are scheduler events that fire per-ticket instead of being batched per-agent.
Additional issue: zombie heartbeat_runs
When a heartbeat fails (adapter error, token limit, process crash), the heartbeat_runs row stays in running status permanently. There is no timeout or cleanup. These zombie rows accumulate and each one triggers scheduler queries, creating a feedback loop with the dependency checker.
Environment
paperclipai@2026.517.0, embedded PostgreSQL, 16 agents.