block / block/buzz

ACP bridge subprocesses are never reaped after an agent turn completes, leaking memory across all harnesses

Open
#4,577 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

**Describe the bug**
When an agent (regardless of which ACP-compatible harness backs it) completes a turn and replies in a channel, the subprocess pool spawned to service that turn is not terminated or reaped. Each single message-to-agent interaction leaves behind roughly 10 idle child processes under the corresponding `buzz-acp` bridge, permanently, with no cleanup even minutes after the agent has finished responding and gone idle (confirmed via CPU dropping to ~0% and staying there).

This is harness-agnostic — reproduced identically with two different backing harnesses (a Claude-based agent and an opencode-based agent) in the same session. In each case, exactly one message produced exactly 10 leftover subprocesses that never exited.

Because this leak is per-message rather than per-session, it compounds continuously during normal use. Over roughly an hour of typical activity (multiple messages across multiple agents), leaked subprocess count reached ~88 processes consuming ~2.2GB RSS and ~2,100 open file descriptors. In a smaller two-message controlled test, 20 leaked processes alone accounted for ~3.78GB RSS and 627 open FDs — the two harnesses differ substantially in per-process footprint (~43MB/process for one harness's subprocesses vs. ~330MB/process for the other's), but both leak at the same ~10-processes-per-turn rate.

The resulting memory/FD pressure correlates with (and is the most likely cause of) several user-visible symptoms during sustained use:
- The relay WebSocket connection intermittently dropping, prompting a manual reconnect
- Sent/received messages failing to render in the UI
- Agents appearing unresponsive to new messages

**Steps to reproduce**
1. Launch Buzz desktop and note the baseline set of `buzz-acp` bridge child processes (e.g. `ps -eo pid,ppid,command | awk '$2=='`) — this is a stable pool with no further children yet.
2. Send a single message to any agent and wait for its reply to appear in the channel.
3. Inspect the children of that agent's `buzz-acp` bridge process (`pgrep -P `) — observe ~10 new subprocesses spawned.
4. Wait several minutes after the agent's reply is visible in the UI. Observe via `ps -o pid,%cpu,stat,etime` that these subprocesses drop to near-0% CPU (idle) but remain alive indefinitely — they are never terminated.
5. Repeat with a different backing harness for a different agent — same ~10-subprocess leak pattern occurs.
6. Repeat step 2 across multiple agents/messages over an extended session — leaked process count, RSS, and FD usage grow linearly and without bound.

**Expected behavior**
Once an agent turn completes and the reply has been delivered, all subprocesses spawned to service that turn should be terminated and reaped by their parent `buzz-acp` bridge. Steady-state process/memory/FD usage should return close to baseline between turns, regardless of which ACP harness backs the agent, and regardless of how many messages are sent over a session's lifetime.

**Version and platform**
- Buzz version: 0.5.3 (0.5.3)
- OS: macOS

**Logs / additional context**
Quantified from a controlled two-message test (one message per harness, one harness-A agent + one harness-B agent):
- 20 leaked subprocesses total (10 per harness), all confirmed idle (~0% CPU) for 10+ minutes after their agent's reply was posted
- ~3.78GB combined RSS across just these 20 processes
- 627 open file descriptors across just these 20 processes
- System-wide memory compressor usage rose to 9.6GB with under 1GB "unused" RAM remaining, from this test alone

From the original (uncontrolled) session that surfaced the symptom: ~88 leaked processes, ~2.2GB RSS, ~2,100 FDs, accumulated over roughly an hour of normal multi-agent usage, including at least one process that became a `` zombie never reaped by its parent. Fully quitting and relaunching the Buzz desktop app clears all leaked processes and temporarily resolves the disconnects/unresponsive-agent symptoms — until the leak reaccumulates with continued use.

---
Filed by Claude on behalf of the reporter.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the leak in the Buzz desktop app and inspect the `buzz-acp` bridge process tree after an agent reply, using the listed `ps` and `pgrep` commands. Trace the subprocess pool lifecycle around turn completion and reply delivery. Done means turn-specific subprocesses are terminated and reaped for both Claude-based and opencode-based harnesses, with process, memory, and file-descriptor usage returning near baseline.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.