Our C: drive hit 230 MB free out of 231 GB. We cleared the obvious junk and got 18 GB back. We also silently wiped the mid-flight tool output of every other Claude session running on the box. They all write to %TEMP%, and we never thought of “clean temp” as a write that touches other processes.
On a machine with one session on it, deleting temp files is housekeeping. On a machine running a swarm of agent sessions, %TEMP% is shared mutable state, and a recursive delete on it lands inside every running process at once. We found that out by doing it and then reading back what we had actually done.
Where the disk went
This was the middle of a marathon day. The box was running half a dozen Claude Code sessions in parallel, most of them mid-task on SaaS tickets, plus background dispatch runs and the conversation-enrichment cron. The trigger was a low-disk warning, then Get-PSDrive C reporting 0.23 GB free. Windows has no graceful degradation at that point. Things just start failing to write, and you go find space.
So we scanned. A recursive size-by-folder in PowerShell produced so much output the shell could barely buffer it, and it gave us the hogs:
AppData\Local: 44 GB<agent-data-dir>\chrome-claude-sessions: 33.9 GB- Recycle Bin: 3.4 GB
Then we did the obvious thing. The cleanup math:
- Recycle Bin: 3.4 GB
- Temp: ~7 GB
- npm cache: 2.0 GB
- Roblox: 5.9 GB
That came to about 18.3 GB, and the drive went from 0.23 GB free to 18.5 GB free. On the surface, problem solved.
It wasn’t. Two things went sideways inside that “~7 GB of Temp.”
Friendly fire
%TEMP% on this box holds more than OS scratch and stale installer files. Claude Code writes per-session tool-call output under ...\Temp\claude\<project>\<session-id>\. Every running session has its own subdirectory there, and it writes a tool call’s output to that directory while the call is in flight, before the result is read back into the conversation.
When we cleared %TEMP%, we cleared all of those, including the ones belonging to sessions we were not working in. Any other session with a pending tool result on disk at that moment may have lost it. Our reasoning had been that temp files are disposable by definition. They are, right up until a live process put them there and is about to read them back. Sitting in a temp directory tells you nothing about whether something is depending on a file.
We did not target the other sessions. We ran a command that felt narrow (clear temp) and was global in effect, on a resource we had stopped treating as shared. The blast radius was every concurrent agent on the machine. We only saw it after the delete, by looking at what had been under that path.
The npm cache gave a smaller tell in the same direction. npm cache clean --force reported success and left about 2 GB sitting in the folder. We had to Remove-Item the directory by hand to actually reclaim the space. Reported success is not verified success, even from your package manager.
The panic delete was treating a symptom
The worse problem is why a one-time cleanup was never going to hold. The 33.9 GB in <agent-data-dir>\chrome-claude-sessions was a cache growing under active use with no retention policy at all. It was not stale junk.
The numbers are specific. That directory held 218 session dirs, and 181 of them had been created in the previous 7 days. Each Claude Code launch that spins up the chrome profile drops roughly 157 MB there and never cleans it up. At that rate the disk refills in a matter of weeks. Deleting it once buys maybe a month. Then we are back at 230 MB free running the same fire drill, probably mid-task, probably under live sessions again.
A panic delete on a directory that regrows 157 MB per launch is a recurring chore. It also carries collateral damage every time, because we would be doing it under load every time.
The fixes
The fixes split along the two failure modes.
For the friendly fire, scope the global cleanups. “Clean temp” has to become “clean the temp entries this session owns, or that no live session owns.” Concretely, that means no blind recursive delete on %TEMP%. Enumerate the ...\Temp\claude\<session-id>\ dirs, cross-reference the session IDs against what is currently running, and touch only the orphans. Or move the volatile per-session scratch off the shared path entirely so a disk cleanup cannot reach it. Either way, stop treating %TEMP% as inert. On this kind of machine it is live shared state, and a delete is a write.
For the cache bloat, the structural fix is a janitor that caps chrome-claude-sessions by age or count and runs on a schedule. That keeps the directory from ever reaching the size where a human has to step in at 230 MB free. The only safe time to clean shared scratch is when nothing is using it, and on a box like this there is almost never such a moment. With a retention sweep in place we never again recover disk by hand while eight sessions are mid-flight.
The move we could not do live
A third thread came out of the same incident. We wanted to relocate Claude’s data directory off C: entirely with a directory junction, mklink /J, so apps see a normal folder. You cannot do that live. Every running session holds open file handles on its projects/*/*.jsonl transcripts and lock files. Windows refuses to rename a directory with open handles, and a junction swapped underneath a running process is not re-resolved anyway, so the process keeps writing where the handle was opened.
So that move got staged behind an abort-guarded script that refuses to run if it sees a claude process. The actual migration has to happen cold, with every window closed. It is the same truth as the temp delete: shared, live state does not tolerate being modified out from under the processes using it.
On a machine running parallel agent sessions, %TEMP% is shared mutable state, and “clean temp” is a write that touches every running process, so scope it to what you own. Put a retention policy on any cache that grows under use, so it stays capped while small and never gets cleared by a panic delete while everything is live.
Related
- Our Agent’s Chrome Was Running but Invisible: A Windows Session 0 Isolation Ghost Story: another case of agent-side shared state behaving unexpectedly on Windows
- Every clone carried the same 12 stashes: spotting a filesystem-copy that duplicated the reflog: shared filesystem state causing unexpected cross-agent contamination
- The clone that stomped another clone’s lock, and the halt gate that should have existed: parallel agents silently overwriting each other’s state with no error
- Same SHAs in Two Repos: Why Commit-Count Metrics Lie in a Clone Workflow: shared git state across the clone fleet producing misleading metrics
- One-Flag Fix: —isolated Stops Parallel Playwright Clones From Deadlocking: parallel agent processes contending over a shared resource