The problem
Claude Code updates itself often, and every update leaves the previous version
on disk. On a remote development machine the same version is usually stored up
to three times: the CLI binary in ~/.local/share/claude/versions/, the editor
extension in ~/.vscode-server/extensions/, and the downloaded VSIX file in the
extension cache. Each copy is 250 to 290 MB, so a small VPS fills up within a
few weeks.
The old copies can be deleted by hand, but each directory has to be checked first: a session started days ago may still run an older binary, and the editor extension runs from its own versioned directory.
How it works
claude-code-gc scans a fixed list
of directories. CLI versions come from ~/.local/share/claude/versions/.
Extensions come from the extension directories of VS Code, Cursor and Windsurf,
and VSIX files from the two VS Code download caches. In the extension and VSIX
directories it only considers entries named anthropic.claude-code-<version>....
It then reads /proc. A version counts as in use when a running process has it
as its executable (/proc/<pid>/exe) or names a file inside it on its command
line. The second case covers the VS Code extension, which runs as
node .../extension.js. Every version in use is kept, and so is the newest
version of each kind (cli, extension, vsix). --keep N keeps the newest N
versions per kind, and --keep 0 keeps only what is in use.
The default is a dry run. This is the example from the README, taken on a VPS with several sessions open:
$ claude-code-gc
cli 2.1.299 253.0 MB in use (pid 324791) ~/.local/share/claude/versions/2.1.299
cli 2.1.300 253.8 MB remove ~/.local/share/claude/versions/2.1.300
cli 2.1.302 272.6 MB in use (pid 1683736) ~/.local/share/claude/versions/2.1.302
extension 2.1.300 266.9 MB remove ~/.vscode-server/extensions/anthropic.claude-code-2.1.300-linux-x64
extension 2.1.301 267.5 MB keep (newest) ~/.vscode-server/extensions/anthropic.claude-code-2.1.301-linux-x64
2 item(s) removable, 520.7 MB. Run with --delete to remove them.
note: pid 3581507 still runs deleted ~/.local/share/claude/versions/2.1.292; its space returns when it exits.
--delete removes the items marked remove. The note lines list
long-running sessions that still execute a binary that was already deleted.
Linux frees that space only when the process exits, so ending old sessions is
the only way to get it back.
The tool needs Python 3.10 or newer and has no dependencies.
Testing
The tests build a fake home directory with three CLI versions, two extension
versions and one unrelated extension, plus a fake /proc with exe symlinks
and cmdline files. They check that other extensions are ignored, that the
newest and the in-use versions are kept, and that an extension counts as in use
through its command line. One test makes sure that a process running 2.1.301
does not mark the directory 2.1.30 as in use. Others cover the report of a
deleted binary that is still running, a dry run followed by --delete, and
--keep 0.
There are 8 tests. CI runs them on Python 3.10, 3.11, 3.12 and 3.13, together
with ruff check and ruff format --check, and runs the command once on the
runner.
Limitations
- It runs on Linux only, because it reads
/procto find running processes. - It scans only the directories listed in the README. Installations in other places are not found.
- Space held by a process that still runs a deleted binary cannot be freed by the tool. It only reports these processes.
The code and installation instructions are at github.com/Jwrede/claude-code-gc.