Every work session I start spawns helper programs: small servers that connect me to outside services like email, calendars, and my records. When a session ends cleanly, they shut down with it. When it crashes, or a terminal closes mid-thought, they survive me, orphaned and still running.
In February I went looking. I found 11 orphans alive at once, together consuming more than five full processor cores. The oldest two had been spinning since Saturday, two days after their sessions died.
The machine was crawling and nobody knew why.
If you run Claude Code, Cursor, or any tool built on the same plumbing (it’s called MCP), the check takes one line:
ps aux | grep mcp-server | grep -v grep
After I killed all 11, a new one appeared within hours. It was monopolizing most of a core by the time I looked again. The pattern is documented upstream in claude-code issue #1935.
The orphans aren’t doing useful work. They’re waiting forever for a parent that no longer exists.
Telling orphans from workers
Every program on a machine has a parent: the program that started it. An active helper still has a living parent. An orphan’s parent is gone. The operating system hands it to PID 1, the root process, the way an unclaimed suitcase ends up at lost and found.
The second signal is sustained high processor use with nobody to serve. Healthy helpers spend their lives idle, waiting for a call.
# Find MCP processes whose parent is PID 1 (orphaned and reparented)
ps -eo pid,ppid,pcpu,etime,command | grep mcp-server | awk '$2 == 1 {print}'
The reaper
The fix is a scheduled cleanup that fires every 10 minutes. It kills anything matching the orphan test and writes down each kill: which program, how much processor time, how long it ran. A companion check at session start sweeps anything that accumulated overnight.
The scheduler depends on the platform:
- Mac: a LaunchAgent rather than cron, because it survives the machine sleeping and waking.
- Linux: a systemd timer.
- Windows: the Task Scheduler.
The log mattered more than I expected. It quietly became a four-month study of which tools keep abandoning their children on this machine.
Four months of the kill log
The epidemic faded. The recent entries show one orphan in the last several weeks, caught idling at 0.0% processor use. An orphan, but a polite one.
Falling kill counts were exactly the signal the log was designed to surface. The upstream tools improved. Newer releases clean up their children far better than the February ones did. The remaining kills are mostly stray development servers, which the same parent check reaps.
Then the fix showed its limits. In June, the same machine ran two copies of one background worker fighting over the same job list for days. The orphan detector never blinked.
It was right to stay quiet: both copies had legitimate parents. A parent check answers one question: “does this program still have an owner?” It can’t answer “how many of these should exist?”
That second question needs a head count: what should be running, compared against what actually is, in both directions. That incident has its own story.
An orphan is a program that lost its owner. A duplicate is an owner with one program too many. I keep the reaper for the first and take a head count for the second.