Clean up Mac storage
Measure first, propose specific targets, clean only approved items, then measure again. The commands below are a menu, not a script to run in full.
Safety defaults
- Start read-only. Before deleting, show each exact path or tool-managed cache, its measured size, the destructive command, and what will be lost or downloaded again. Obtain explicit approval for those targets and impacts. A request to inspect storage or write cleanup instructions does not authorize deletion.
- Quit affected apps and stop model jobs, downloads, builds, and hooks before clearing their caches. Caches will be rebuilt or downloaded again; this costs time/bandwidth, can break offline workflows, and assumes the original content is still available. Preserve locally authored or irreplaceable files.
- Treat paths below as defaults, not proof of what is stored there. Check cache
configuration and symlinks, inspect resolved paths, and use quoted, explicit
targets. Never feed unchecked environment variables, globs, or discovery
output directly to
rm -rf. A directory namedCachescan contain user state. - Never blanket-delete
~/Library,~/.cache,~/Library/Caches, Application Support, Chrome/Arc profiles, or MobileSync backups. Do not usesudo rm, disable macOS protections, or empty Trash as part of routine cache cleanup. - Skip absent paths/tools; do not install or upgrade software just to inspect storage. Permission errors mean totals may be incomplete, not that a directory is empty. Report access limits; do not automatically elevate privileges.
1. Inspect storage
Use macOS/BSD du syntax. Start shallow and drill into large locations only.
Keep permission errors visible. System Data is a storage category, not a
directory to delete.
df -h "$HOME"
du -h -d 1 "$HOME/Library" | sort -h
du -h -d 1 "$HOME/.cache" | sort -h
du -h -d 1 "$HOME/Library/Caches" | sort -h
du -h -d 1 "$HOME/Library/Application Support" | sort -h
# Deeper inspection when needed:
du -h -d 2 "$HOME/Library" | sort -h | tail -40
du -h -d 2 "$HOME/.cache" | sort -h | tail -40
Make a short table of candidate, current size, contents, expected impact, and
proposed command. Do not reuse historical GB estimates or double-count parent
directories and their children. APFS snapshots, clones, and hard links can make
directory totals differ from space actually recoverable. If a cache resolves to
another volume, record df -h for that path too; deleting from an external disk
does not free internal storage.
2. Development caches
Resolve configured locations before measuring or removing anything:
| Cache | Location/configuration to check |
|---|---|
| Hugging Face | Usually ~/.cache/huggingface; check HF_HOME, XDG_CACHE_HOME, HF_HUB_CACHE, HF_DATASETS_CACHE, HF_XET_CACHE, HF_ASSETS_CACHE, and legacy TRANSFORMERS_CACHE overrides. |
| uv | Use uv cache dir; respect UV_CACHE_DIR and uv configuration instead of assuming ~/.cache/uv. |
| pre-commit | PRE_COMMIT_HOME, otherwise ${XDG_CACHE_HOME:-$HOME/.cache}/pre-commit. |
| pip | Use the intended interpreter's python3 -m pip cache dir and cache info; respect PIP_CACHE_DIR and pip configuration. On macOS it is often ~/Library/Caches/pip. |
Read only relevant path settings, not the entire environment or credential files. Use the same environment/configuration for inspection and cleanup.
# Default-path examples; substitute resolved paths if configuration differs.
du -h -d 2 "$HOME/.cache/huggingface" | sort -h | tail -30
du -sh "$HOME/.cache/pre-commit"
uv cache dir
python3 -m pip cache dir
python3 -m pip cache info
Measure the exact directory returned by each tool with du -sh before proposing
cleanup. Check installed --help when command availability is uncertain.
Hugging Face
HF_HOME also holds login tokens, including token and stored_tokens; do not
delete the whole root as routine cleanup. Preserve any configured HF_TOKEN_PATH
without reading its contents. Prefer the installed hf cache CLI
for Hub entries: inspect with supported hf cache ls / hf cache prune --dry-run,
then offer targeted hf cache rm or hf cache prune after approval, retaining
confirmation prompts. Hub commands do not necessarily clear processed datasets,
Xet, assets, or legacy diffusers caches.
When full eviction of an inspected cache is explicitly approved, these are default-path alternatives. Select only approved lines, and confirm that no locally saved models, datasets, or credentials are inside the selected target:
# DESTRUCTIVE: individually approved, verified cache directories only.
rm -rf -- "$HOME/.cache/huggingface/hub"
rm -rf -- "$HOME/.cache/huggingface/datasets"
rm -rf -- "$HOME/.cache/huggingface/diffusers"
rm -rf -- "$HOME/.cache/huggingface/xet"
rm -rf -- "$HOME/.cache/huggingface/assets"
See Hugging Face cache management and cache/token locations.
uv, pre-commit, and pip
Use the owning tool for cleanup. For uv, never manually remove cache files:
its cache has internal structure and locking. Check for UV_LINK_MODE=symlink
or link-mode = "symlink" first; deleting referenced cache files can break those
environments. This warning applies to both prune and clean. Explain the need
to recreate affected environments before approval.
# DESTRUCTIVE: choose approved operations, not every line.
uv cache prune # Remove unused entries; prefer to full eviction.
uv cache clean # Alternative: clear the whole uv cache.
pre-commit gc # Remove unused cached hook repositories.
pre-commit clean # Alternative: clear all cached hook environments.
python3 -m pip cache purge # Remove this pip configuration's HTTP/wheel cache.
Hook environments and packages may need rebuilding/reinstalling. Check uv cache guidance, uv link-mode settings, pre-commit commands, and pip cache commands as needed.
3. Browser and app caches
Inspect the common candidates individually, with their apps closed before any cleanup. Prefer an app's cache-only clearing control when available; do not select cookies, passwords, history, site storage, or offline downloads implicitly.
du -h -d 2 "$HOME/Library/Caches/Arc" | sort -h | tail -30
du -h -d 2 "$HOME/Library/Caches/Google" | sort -h | tail -30
du -h -d 2 "$HOME/Library/Caches/com.spotify.client" | sort -h | tail -30
du -h -d 2 "$HOME/Library/Caches/ms-playwright" | sort -h | tail -30
Only if inspection confirms an entire target is disposable cache, offer these individual deletions. If it mixes cache and user state, select verified cache subdirectories instead. Leave Arc and Spotify Application Support untouched; inspect Google Application Support separately as described below.
# DESTRUCTIVE: select only inspected, cache-only, approved targets.
rm -rf -- "$HOME/Library/Caches/Arc"
rm -rf -- "$HOME/Library/Caches/Google"
rm -rf -- "$HOME/Library/Caches/com.spotify.client"
For Spotify, prefer Settings > Storage > Clear cache; downloaded music is a separate decision. See Spotify storage guidance.
Playwright
Respect PLAYWRIGHT_BROWSERS_PATH and project-local installations. Do not remove
the whole ms-playwright directory: Playwright MCP persistent profiles
can live there as mcp-*-profile and contain login/site data. Preserve those and
any custom user-data directories. Inspect browser binary directories separately.
Prefer an already-installed project's CLI, after checking its uninstall help and confirming its removal scope preserves persistent profiles. If that scope is unclear, do not run it; propose individually verified browser-binary directories instead.
# DESTRUCTIVE: example for an existing Node project's Playwright installation.
./node_modules/.bin/playwright uninstall
For a Python project, use that environment's python3 -m playwright uninstall
instead. Do not download a CLI just to clean up or add --all without explicit
approval of its wider scope. Browser binaries must be reinstalled with the
project's Playwright version before tests can run again. See
Playwright browser management.
4. Google Application Support and Chrome profiles
Do not delete ~/Library/Application Support/Google, the Chrome directory,
Default, or a whole Profile N. These hold actual browsing state and extensions.
IndexedDB, Local Storage, Service Worker storage, and extensions are not routine
disposable caches. An unfamiliar profile is not evidence that it is abandoned.
du -h -d 2 "$HOME/Library/Application Support/Google" | sort -h | tail -40
# Example only: replace Profile 5 with the profile actually identified.
du -h -d 2 "$HOME/Library/Application Support/Google/Chrome/Profile 5" | sort -h | tail -40
Use Chrome's chrome://version to identify the active Profile Path, or map
default-location profile directories to names without dumping the full Local
State file or account emails:
python3 - <<'PY'
import json
from pathlib import Path
state = Path.home() / "Library/Application Support/Google/Chrome/Local State"
profiles = json.loads(state.read_text()).get("profile", {}).get("info_cache", {})
for directory, info in sorted(profiles.items()):
print(f"{directory} -> {info.get('name', '(unnamed)')}")
PY
Inspect these two narrower candidates separately. The on-device model is a downloaded component; removing it can interrupt AI features and Chrome may download it again. The updater cache contains downloaded update packages. Quit Chrome and wait for any updater activity to finish before approved deletion.
du -sh "$HOME/Library/Application Support/Google/Chrome/OptGuideOnDeviceModel"
du -sh "$HOME/Library/Application Support/Google/GoogleUpdater/crx_cache"
# DESTRUCTIVE: only these confirmed, approved component/cache directories.
rm -rf -- "$HOME/Library/Application Support/Google/Chrome/OptGuideOnDeviceModel"
rm -rf -- "$HOME/Library/Application Support/Google/GoogleUpdater/crx_cache"
Do not remove GoogleUpdater itself or disable updates. Model paths can change; consult Chrome model management if the observed layout differs.
5. Snapshots and device backups: inspect, do not clean by default
tmutil listlocalsnapshots /
du -h -d 1 "$HOME/Library/Application Support/MobileSync/Backup" | sort -h
- Time Machine: local snapshots are restore points, not ordinary caches.
macOS normally reclaims them automatically and counts their space as available.
Do not sum snapshot sizes with cache estimates. Leave them alone unless the
user separately approves losing specific restore points; consult the installed
man tmutilbefore proposing any removal. Do not bulk-delete or thin snapshots as part of routine cleanup. See Apple's local snapshot guidance. - MobileSync: these are real iPhone/iPad backups. Do not delete the Backup directory or arbitrary files inside a backup. If the user wants to remove an identified obsolete backup, prefer Finder > connected device > General > Manage Backups, preserving the only usable backup. Obtain separate approval for the selected backup. See Apple's backup management instructions.
6. Verify and report
After approved cleanup, repeat df -h on each measured volume and du -sh for
remaining target directories. Report what actually succeeded, what was skipped,
before/after free space, and what must be downloaded or rebuilt. Do not claim
space was recovered merely because a command was proposed or a directory was
removed; APFS accounting and active apps can affect the measured change.