Codegraph Daemon (v0.9.7) — MCP Mode Main Thread Spin Loop
Summary
Codegraph daemon (v0.9.7) running with --mcp flag enters a busy-wait / spin-loop on its main thread when no MCP client is connected, consuming 100% of one CPU core.
Evidence
Single-thread CPU burn
- Main thread only (TID 1): utime=94433 ticks, stime=2238 — 100% user-space CPU
- 6 worker threads: all idle (utime ~0)
Dense "fake" syscall pattern
| Metric |
Value |
Write syscalls (syscw) |
13.4 million in ~15 min (~15,000/sec) |
Actual bytes written (wchar) |
22,806 bytes total — ~1.7 bytes per call |
| SQLite DB modification time |
Not changed during the spin |
Extremely high write syscall count with near-zero actual data — classic kernel-level spin signature.
Involuntary context switching
| Metric |
Value |
| Voluntary context switches |
18,278 |
| Involuntary context switches |
101,259 |
| Ratio |
5.5:1 involuntary >> voluntary |
Process is preempted by the kernel scheduler, not voluntarily sleeping — confirms CPU starvation pattern.
No clients connected — nothing to do
- Unix socket file is empty (0 bytes) — no MCP client connected
- File watcher disabled (
CODEGRAPH_NO_WATCH=1) — not file-change driven
- Process state: R (running) — always runnable
Root Cause
MCP Daemon Main Loop
│
▼
io_uring / epoll wait?
│
No event → no client
│
▼
⚠ BUG: devolves into busy-poll
- io_uring non-blocking poll
- epoll_wait(timeout=0)?
- No sleep, no blocking
│
▼
~15k syscalls/sec
0 bytes real I/O
100% single-core CPU
When no MCP client is connected, the main event loop degenerates into a non-blocking poll that retries immediately with zero sleep. Under normal operation with an active client, read/write operations naturally block the thread, hiding the bug.
Impact
| Dimension |
Assessment |
| Functionality |
None (no clients connected, no requests processed) |
| CPU |
100% of one core |
| Memory |
Normal (~212 MB RSS) |
| Disk |
Near-zero writes |
| Other processes |
CPU contention if resources are tight |
Workaround
The daemon auto-restarts on demand. The bug only manifests during idle periods — active queries interrupt the spin naturally.
Environment
- codegraph version: v0.9.7
- Launch args:
codegraph serve --mcp
- Platform: Linux x86_64
- SQLite mode: WAL, synchronous=FULL
Codegraph Daemon (v0.9.7) — MCP Mode Main Thread Spin Loop
Summary
Codegraph daemon (v0.9.7) running with
--mcpflag enters a busy-wait / spin-loop on its main thread when no MCP client is connected, consuming 100% of one CPU core.Evidence
Single-thread CPU burn
Dense "fake" syscall pattern
syscw)wchar)Extremely high write syscall count with near-zero actual data — classic kernel-level spin signature.
Involuntary context switching
Process is preempted by the kernel scheduler, not voluntarily sleeping — confirms CPU starvation pattern.
No clients connected — nothing to do
CODEGRAPH_NO_WATCH=1) — not file-change drivenRoot Cause
When no MCP client is connected, the main event loop degenerates into a non-blocking poll that retries immediately with zero sleep. Under normal operation with an active client, read/write operations naturally block the thread, hiding the bug.
Impact
Workaround
The daemon auto-restarts on demand. The bug only manifests during idle periods — active queries interrupt the spin naturally.
Environment
codegraph serve --mcp