You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Codebase-memory opening a huge number of file descriptors #70
⏺ Bash(lsof 2>/dev/null | awk '{print $1}' | sort | uniq -c | sort -rn | head -15)
⎿ 161770 codebase-
11044 node
1420 com.apple
1154 plugin-co
742 corespotl
721 zen
680 Browser
640 Notion
631 python3.1
615 Amazon
456 Dia
451 zed
450 Linear
426 Raycast
425 Music
11:12 AM claude-opus-4-6
⏺ There's your culprit: codebase- (codebase-memory-mcp) has 161,770 open files — that's 88% of your system's total. Your system limit is 184,320 and you have 194,389 open files trying to be used.
Not sure exactly how this has happened, but I do constantly see claude trying to re-index projects that were already indexed. Wouldn't surprise me if that was related
We investigated the C codebase thoroughly and cannot find a file descriptor leak — every fopen/fclose, popen/pclose, and sqlite3_open/sqlite3_close pair is balanced across all code paths.
A few questions to narrow this down:
Which version are you running? (codebase-memory-mcp --version) — if it's v0.4.x (Go), the C rewrite in v0.5.0+ has a completely different architecture that avoids many of the Go runtime's FD accumulation patterns.
How many MCP server processes are running? (pgrep -c codebase-memory-mcp) — Zed may spawn multiple instances that each open stores + git subprocesses. The lsof count is per-system, not per-process.
Is auto-index or the watcher running? The watcher polls git via system() / popen() on every cycle. If an MCP server process isn't cleanly terminated, the watcher thread keeps spawning git subprocesses indefinitely.
If you're on v0.4.x, updating to v0.5.3+ would be the first thing to try. If you're already on v0.5.x and can reproduce, lsof -p <pid> for a single process would tell us exactly what's being held open.
The entire codebase was rewritten from Go to C in v0.5.0. The Go runtime's garbage collector and goroutine scheduler were likely responsible for the high file descriptor count you observed. The C implementation uses explicit file handle management with deterministic open/close patterns.
We investigated all fopen/fclose, popen/pclose, and sqlite3_open/close paths in the C code and found no leaks. If you're still seeing high fd counts, it would likely be from the watcher's git subprocess polling — could you share lsof -p $(pgrep codebase-memory-mcp) | wc -l after ~10 minutes of runtime?
Closing — this was likely caused by the Go runtime's goroutine scheduler and garbage collector. The entire codebase was rewritten from Go to C in v0.5.0 with explicit file handle management and deterministic open/close patterns. We investigated all fopen/fclose, popen/pclose, and sqlite3_open/close paths in the C code and found no leaks.
If you're still seeing high file descriptor counts on v0.5.5+, please reopen with the output of lsof -p $(pgrep codebase-memory-mcp) | wc -l after ~10 minutes of runtime.
Activity
DeusData commentedon Mar 18, 2026
Interesting. Can you maybe share what OS/hardware you use? Will dig into this. This should not happen
DeusData commentedon Mar 20, 2026
We investigated the C codebase thoroughly and cannot find a file descriptor leak — every
fopen/fclose,popen/pclose, andsqlite3_open/sqlite3_closepair is balanced across all code paths.A few questions to narrow this down:
Which version are you running? (
codebase-memory-mcp --version) — if it's v0.4.x (Go), the C rewrite in v0.5.0+ has a completely different architecture that avoids many of the Go runtime's FD accumulation patterns.How many MCP server processes are running? (
pgrep -c codebase-memory-mcp) — Zed may spawn multiple instances that each open stores + git subprocesses. Thelsofcount is per-system, not per-process.Is auto-index or the watcher running? The watcher polls git via
system()/popen()on every cycle. If an MCP server process isn't cleanly terminated, the watcher thread keeps spawning git subprocesses indefinitely.If you're on v0.4.x, updating to v0.5.3+ would be the first thing to try. If you're already on v0.5.x and can reproduce,
lsof -p <pid>for a single process would tell us exactly what's being held open.DeusData commentedon Mar 21, 2026
@jonnyom Is this still happening on v0.5.5?
The entire codebase was rewritten from Go to C in v0.5.0. The Go runtime's garbage collector and goroutine scheduler were likely responsible for the high file descriptor count you observed. The C implementation uses explicit file handle management with deterministic open/close patterns.
We investigated all
fopen/fclose,popen/pclose, andsqlite3_open/closepaths in the C code and found no leaks. If you're still seeing high fd counts, it would likely be from the watcher'sgitsubprocess polling — could you sharelsof -p $(pgrep codebase-memory-mcp) | wc -lafter ~10 minutes of runtime?DeusData commentedon Mar 23, 2026
Closing — this was likely caused by the Go runtime's goroutine scheduler and garbage collector. The entire codebase was rewritten from Go to C in v0.5.0 with explicit file handle management and deterministic open/close patterns. We investigated all fopen/fclose, popen/pclose, and sqlite3_open/close paths in the C code and found no leaks.
If you're still seeing high file descriptor counts on v0.5.5+, please reopen with the output of
lsof -p $(pgrep codebase-memory-mcp) | wc -lafter ~10 minutes of runtime.jonnyom commentedon Apr 7, 2026
Hey @DeusData really sorry, missed your messages, only just got notified.
I'll check out the new version and see