diff --git a/Sources/Homelab/2026-05-18-claude-desktop-subprocess-leak-memory-management.md b/Sources/Homelab/2026-05-18-claude-desktop-subprocess-leak-memory-management.md new file mode 100644 index 0000000..fb4a282 --- /dev/null +++ b/Sources/Homelab/2026-05-18-claude-desktop-subprocess-leak-memory-management.md @@ -0,0 +1,38 @@ +--- +created: '2026-05-18' +path: Sources/Homelab +project: herbys-dev-setup +tags: +- claude-code +- dispatch +- automation +type: session-notes +--- + +## Outcome + +Identified that Claude Desktop on `us-test-authy` accumulates Dispatch subprocess zombies that consume substantial RAM (~10.6GB across 41 processes observed during this session). Closed Desktop to recover ~7GB immediately. Parked the long-term fix as a follow-on — daily nightly stop via user systemd timer is the leading approach. + +## Topics Covered + +- Diagnosed RAM pressure on `us-test-authy` (13/23GB used, hunting for the cause) +- Found 41 `claude` subprocesses totaling 10.6GB, all parented to the live Claude Desktop electron process (PID 183216) — not orphaned, just never reaped +- Subprocesses ranged from ~6h to 8 days old; oldest were Dispatch sessions long abandoned +- Confirmed the pattern: Desktop spawns `claude --output-format stream-json` subprocesses per Dispatch session, doesn't SIGTERM them on session end, they sit idle attached to the parent +- Closing Claude Desktop killed the parent and all children together — clean recovery +- Discussed reaper-cron vs. parent-restart approaches; parent-restart wins on simplicity + +## Key Learnings + +- The subprocess leak is structural, not a cron-able janitor problem. The parent is alive and "owns" the children; they don't get cleaned up until the parent dies. +- This is the same failure mode the dispatch-replacement work is designed to eliminate (harness owns subprocess lifecycle explicitly). Tonight produced concrete evidence for why that work matters. +- User systemd timer is the right mechanism, not root cron — Claude Desktop is a GUI Electron app tied to the user session and DBus. +- "Just stop, don't restart" is cleaner — at 4am there's no graphical session to relaunch into, just stop and let user relaunch on next sign-in. + +## Follow-ons + +- [ ] Decide whether to implement the user systemd timer (stop-only at 04:00) or rely on manual daily quit-and-relaunch +- [ ] If implementing the timer: confirm hour doesn't conflict with any Lovebug overnight work, then write `~/.config/systemd/user/claude-desktop-nightly-stop.{service,timer}` +- [ ] Verify Manjaro tower exhibits the same leak pattern; if so, deploy same fix via Ansible +- [ ] File observation as input to dispatch-replacement design — subprocess lifecycle ownership is a hard requirement, validated by this incident +- [ ] Optional safety-net: memory-pressure alert cron (notify if `free -h` available drops below 4GB) \ No newline at end of file