Blog / claude code
Claude Code using too much memory? Find the old sessions
See how much memory each Claude Code or Codex session uses with its tool servers, find sessions open for days and leftovers, and close them safely.
Your laptop fan spins up, Activity Monitor shows a wall of node and claude processes, and you have no idea which terminal they belong to. Usually nothing is broken. Each coding agent session starts helpers of its own (tool servers, language servers, shells, dev servers), and each one keeps running until its session ends. Leave ten sessions open for a week and they add up.
This post gives you one script that shows the real memory of each session with all its helpers, how to spot the ones you forgot, and how to close them without losing work. We ran everything below on a Mac with sixteen Claude Code sessions open, and the script on Linux too.
Why one session is more than one process#
When you start claude or codex in a folder, the agent process itself typically uses a few hundred MB. On top of that it starts:
- Tool servers from your config: each entry under your agent's tool server settings is its own program, often launched through
npxoruvx, so you get a package runner plus the server itself. - Shells for the commands it runs.
- Anything those commands start: a dev server, a test watcher, a build in watch mode.
Activity Monitor and top list them one by one, with no link to the session that started them. A session with eight tool servers can be fifteen processes. So the question to ask isn't "which process is big" but "which session is big, counting everything under it".
Step 1: memory per session, helpers included#
Save this as agent-mem.sh:
#!/bin/bash
# agent-mem.sh: memory used by each Claude Code or Codex session, helpers included.
tree() {
local p
for p in "$@"; do
echo "$p"
tree $(pgrep -P "$p")
done
}
for pid in $(pgrep -x claude) $(pgrep -x codex); do
kb=0; n=0
for p in $(tree "$pid"); do
r=$(ps -o rss= -p "$p" 2>/dev/null)
kb=$((kb + ${r:-0})); n=$((n + 1))
done
dir=$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p')
printf '%6s MB %3s procs up %-12s %-7s pid %-6s %s\n' \
"$((kb / 1024))" "$n" "$(ps -o etime= -p "$pid" | tr -d ' ')" \
"$(basename "$(ps -o comm= -p "$pid")")" "$pid" "$dir"
done | sort -rnRun it with bash agent-mem.sh. It walks the process tree under each session, adds up resident memory, and prints the biggest first, with how long the session has been open and the folder it runs in. On our Mac the top of the list looked like this (folders shortened):
4694 MB 18 procs up 07:36 claude pid 96503 ~/app
2577 MB 19 procs up 52:14 claude pid 98954 ~/app
958 MB 14 procs up 19:53 claude pid 18925 ~/app
679 MB 11 procs up 02-08:57:58 claude pid 47751 ~/app
679 MB 7 procs up 05-08:01:34 claude pid 24431 ~/app
660 MB 14 procs up 05-08:04:05 claude pid 4827 ~/siteThree things to read from it:
- The big ones at the top. The 4.7 GB session had been open only seven and a half minutes and was busy. A big number on a young, busy session is usually work in progress, not a leak.
- The old ones:
up 05-08:01:34means five days and eight hours. Sessions open that long are usually forgotten ones, and each still held 600-700 MB with its tool servers. - The process count. Fourteen processes for a session that does nothing is a sign of many tool servers. Every one you configured starts again in every session.
On Linux, lsof is often missing; swap the dir= line for dir=$(readlink "/proc/$pid/cwd"). We ran that version in a Debian container and it printed the same columns.
Step 2: find what was left behind#
When a session ends normally, its helpers end with it. When it is killed, or a command started something with nohup or &, those children can outlive it. The system then adopts them, so their parent process ID becomes 1. List the likely ones:
pgrep -P 1 -lf 'npm exec|npx|uvx|node 'On our Mac this found four npm exec vite servers whose sessions were long gone, each still holding a port. Before you stop one, check what it is and which folder it runs in:
ps -o pid,etime,rss,command -p 34796
lsof -a -p 34796 -d cwdIf it is clearly yours and clearly finished (an old preview server, a watcher for a folder you closed), stop it with kill 34796, and only use kill -9 if it ignores that. Don't kill system processes or anything you don't recognise; the pattern above also matches things you may have started on purpose.
On Linux desktops, orphans may be adopted by your user's service manager instead of process 1. If the list comes back empty, look for processes whose parent is systemd --user.
For ports specifically, see Port already in use? Find the dev server your agent left.
Step 3: close old sessions the right way#
The safest way to get a session’s memory back is to end the session itself, not to kill its helpers one by one:
- Find its terminal (the folder in the last column helps), make sure it isn't in the middle of something, and type
/exitor press Ctrl+D. - If you can't find the terminal,
kill <pid>on the agent process sends a normal stop signal; its tool servers end with it. - Need the conversation again later?
claude --resumeorcodex resumebrings it back. Ending a session doesn't delete its history.
Then run agent-mem.sh again and check the list got shorter.
Keep it from piling up#
- Trim tool servers you don't use. Each one starts in every session. Removing three you never call saves three processes per session, every session.
- Keep project-only servers in the project. A database server needed for one repo belongs in that repo's config, not your user config.
- Close sessions when the job is done. Resuming later is cheap; an idle session holds its memory all week.
- Ask agents to stop what they start. A line in your
CLAUDE.mdorAGENTS.mdlike "Stop any dev server or watcher you started before you finish" helps.
Where Joxo fits#
Most of this mess comes from having many terminals and losing track of them. The Joxo desktop app puts every agent session on your computer in one window: what each one is doing, which need you, and which are done, so you can close the finished ones instead of hunting for them. When an agent needs an answer, the question reaches your phone too. Get it from the download page. For running several sessions without the chaos, see manage many Claude Code sessions.
Frequently asked questions#
Why does Claude Code use so much memory?#
The agent itself usually takes a few hundred MB. The rest comes from what it starts: tool servers from your config, shells, and dev servers or builds. Count a session together with its child processes to see its real size.
How do I see which Claude Code sessions are running?#
Run pgrep -lx claude for the list of session processes, or the script in this post for each one's memory, age and folder.
Is it safe to kill leftover node processes?#
Only once you know what they are. Check the command and folder with ps and lsof first, stop the ones you recognise as finished, and leave anything you don't recognise.