When my Mac warned me again that the disk was almost full, the data volume was about 460GiB, with 409GiB used and only 3GiB actually available. After investigation and cleanup, available space was back to 72GiB. The main lesson this time: you can’t simply add up the directory sizes reported by du and treat the total as reclaimable space; APFS clones, Docker virtual disks, and swap can all cause the reported figures to differ from the change shown by df.
Where to Start Looking
First, use df -h /System/Volumes/Data to confirm the actual available space, then use du -x -d 1 -h to work down through the directories. The main consumers in the first pass were the user directory, ~/Library, the system temporary directory, and the Trash. Looking deeper, the temporary directory contained a group of com.google.Chrome.code_sign_clone directories, totaling about 52GiB on paper: dozens of copies of the Chrome application, each about 1.4GiB.
These weren’t Chrome browsing data; browser profiles were stored elsewhere. After checking each copy’s path and modification time, I removed 43 old copies and kept the newest one at the time. Because APFS data blocks may be shared, the 52GiB reported by du doesn’t mean deleting them will necessarily free up 52GiB. The actual result has to be checked with df.
What I Cleaned Up
- Emptied the Trash. It mostly contained old application copies, and emptying it freed up about 22GiB of actual space.
- Deleted old Chrome code-signing copies, keeping the newest one; this freed up about 10GiB of actual space.
- Used
docker volume pruneto remove 370 volumes that weren’t being used by any containers. Before cleanup, Docker reported about 14.85GiB as reclaimable; afterward, only one active volume remained, and OrbStack’s virtual disk usage decreased as well. - Cleared rebuildable caches for npm, pnpm, uv, and Go, along with
target/build artifacts from several Rust projects. These files will be regenerated on the next build.
I worked in batches throughout the process, checking df again after each batch. In the end, available space on the data volume went from 3GiB back to 72GiB. The directory sizes for individual batches and the final net increase measure different things, so I didn’t add them together to estimate the result.
What I Kept
Chat histories, browser profiles, application containers, and personal files were not treated as caches. I also didn’t immediately delete the Git worktree left by an inspection tool, because it might have been a working checkout. System swap was using about 23GiB at the time; that’s related to memory pressure and isn’t something to resolve by manually deleting swap files.
The sequence from this investigation can be reused: confirm actual available space first, then locate usage by directory; distinguish caches, copies, and real data; verify with df after every batch of cleanup. Use the figures reported after disk usage has been recalculated.
