Critical: File Descriptor Leak Causing 512GB Memory Bloat

Resolved 💬 4 comments Opened Jan 29, 2026 by BugorBN Closed Mar 1, 2026

Critical Memory Leak: File Descriptor Leak in Claude CLI

Summary

Claude CLI has a severe file descriptor leak that causes memory consumption to grow over time. The process never closes file handles to .claude.json configuration files, leading to hundreds of leaked file descriptors and virtual memory bloat to 512GB+ after extended runtime.

Environment

  • Claude CLI Version: 2.1.23 (Claude Code)
  • OS: macOS (Darwin 25.2.0)
  • Platform: darwin
  • Date Observed: 2026-01-29

Symptoms

  1. Claude process memory (VSZ) grows to 512GB+ virtual memory
  2. Process accumulates 165+ open file descriptors to the same config file
  3. Memory consumption increases over time regardless of project
  4. Affects all Claude CLI instances (tested with multiple config directories)

Root Cause

The Claude CLI process does not properly close file descriptors after reading/writing configuration files (.claude.json and backup files). Each config operation opens a new file handle but never closes it.

Evidence

Process Metrics (after 15+ hours runtime)

PID: 4529
VSZ (Virtual Memory): 512,459,008 KB (~512GB)
RSS (Resident Memory): 175,696 KB (~175MB)
CPU: 25.9%
Runtime: 149 minutes active session

File Descriptor Leak

$ lsof -p 4529 | grep ".claude.json" | wc -l
165

$ lsof -p 4529 | grep -E "\.jsonl|\.json" | wc -l
170

Sample output showing duplicate handles to the same file:

claude  4529 bugorbn   16r  REG  1,14  31436  /Users/bugorbn/.claude-praktika/.claude.json
claude  4529 bugorbn   50r  REG  1,14  29387  /Users/bugorbn/.claude-praktika/.claude.json
claude  4529 bugorbn   53r  REG  1,14  29527  /Users/bugorbn/.claude-praktika/.claude.json
claude  4529 bugorbn   68r  REG  1,14  31436  /Users/bugorbn/.claude-praktika/.claude.json
claude  4529 bugorbn   97r  REG  1,14  31091  /Users/bugorbn/.claude-praktika/.claude.json
claude  4529 bugorbn  100r  REG  1,14  29600  /Users/bugorbn/.claude-praktika/.claude.json
... (165 total handles to config files)

Excessive Config Writes

Debug logs show the config file is being written excessively:

$ grep -c "Writing config file" current-session-debug.log
236

With "High write ratio" warnings appearing throughout the session.

Reproduction Steps

  1. Start Claude CLI in any project
  2. Let it run for several hours with normal usage
  3. Check open file descriptors: lsof -p $(pgrep claude) | grep ".claude.json" | wc -l
  4. Check virtual memory: ps aux | grep claude
  5. Observe hundreds of leaked file descriptors and 512GB+ VSZ

Expected Behavior

  • File descriptors should be closed immediately after config read/write operations
  • VSZ should remain stable around 1-2GB
  • Number of open file descriptors should be < 50

Actual Behavior

  • File descriptors accumulate indefinitely (165+ observed)
  • VSZ grows to 512GB+ after extended runtime
  • Each config operation leaks file handles

Impact

  • Severity: High
  • Frequency: Always (100% reproduction rate)
  • Scope: All users running Claude CLI for extended periods
  • Workaround: Restart Claude CLI periodically

Additional Context

Multiple Config Directories Affected

Tested with two different Claude config directories, both exhibit the same leak:

  • /Users/bugorbn/.claude/ (8.4GB total size)
  • /Users/bugorbn/.claude-praktika/ (678MB total size)

System Resources

$ du -sh ~/.claude*/
678M    /Users/bugorbn/.claude-praktika/
8.4G    /Users/bugorbn/.claude/

$ ls -lh ~/.claude*/history.jsonl
-rw-r--r--  1 bugorbn  staff  1.5M  /Users/bugorbn/.claude-praktika/history.jsonl
-rw-------  1 bugorbn  staff  1.4M  /Users/bugorbn/.claude/history.jsonl

Suggested Fix

The file I/O operations for .claude.json need to properly close file descriptors. Likely locations:

  1. Config file read operations
  2. Config file write/backup operations
  3. Any file watching or monitoring code

Recommend auditing all file system operations for proper resource cleanup using try-finally blocks or RAII patterns.

Workaround

Users can mitigate by:

# Restart Claude regularly
killall claude

# Monitor file descriptors
lsof -p $(pgrep claude) 2>/dev/null | wc -l

---

Reporter: User via Claude CLI debugging session
Date: 2026-01-29

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗