Dustloft

How to clear System Data on a Mac without breaking anything

Guide · 8 min read · Updated September 2026

Short answer: find out what is inside System Data before deleting anything. Use du -kxd 1 to measure each folder, work from the largest item down, and never delete a .git directory, anything inside a cloud-synced folder, or a Docker volume.

Every guide that tells you to empty ~/Library/Caches is aiming at the wrong target. This one starts by measuring.

Step 1 — See where the space actually went

Open Terminal and run this. It measures every folder in your home directory in one pass:

du -kxd 1 ~ 2>/dev/null | sort -rn | head -20

The flags matter. -x stays on one filesystem so it does not wander into mounted volumes, -d 1 stops at one level deep, and -k reports in kilobytes so sort -rn orders correctly.

Repeat it one level down on whatever is largest:

du -kxd 1 ~/Library 2>/dev/null | sort -rn | head -20

A warning about the obvious command

Almost every guide online suggests du -sh ~/*. That command silently skips every hidden folder, because the shell glob * does not match names beginning with a dot. On the machine used for this guide it hid 55 GB: ~/.ollama at 16 GB, ~/.cache at 10 GB and ~/.Trash at 9.3 GB were all invisible. Use du -kxd 1 ~ instead, which includes them.

Step 2 — Empty the Trash properly

Check what is in it first, because deleted applications often leave root-owned files that refuse to delete normally:

du -kxd 1 ~/.Trash | sort -rn | head

If normal emptying fails, the items are owned by root and need elevation.

Step 3 — Remove leftovers from apps you uninstalled

Uninstalling never removes these. Look for folders belonging to applications you no longer have:

du -kxd 1 ~/Library/Application\ Support ~/Library/Containers 2>/dev/null | sort -rn | head -20

Folder names are reverse-DNS bundle identifiers, so com.microsoft.teams2 belongs to Teams. If the application is gone, its folder is dead weight. Leave anything starting com.apple. alone.

Step 4 — Reclaim developer space

If you write code, this is usually where the bulk is:

# Dependency folders — restored by npm install
find ~/Projects -type d -name node_modules -prune | wc -l

# Docker: removes unused images, never volumes
docker system prune -a

# Local AI models
ollama list

Docker deserves a note. docker system prune -a is safe because it never touches named volumes, which is where database data lives. Never add --volumes unless you know precisely what you are discarding.

Step 5 — Check for one enormous file

mdfind -onlyin ~ "kMDItemFSSize > 1000000000" 2>/dev/null

Forgotten screen recordings, video editing scratch caches and virtual machine disks all show up here.

Things you must never delete

Do not touchWhy
.git directoriesMay be the only copy of a project's history
Anything in Dropbox, iCloud Drive, OneDriveA local delete syncs to every device
Docker volumesContain database data, not cache
com.apple.* containersSystem components
Your MySQL or Postgres data directoryContains actual databases

The .git trap specifically

A repository with a remote configured looks backed up. It is not, until something has actually been pushed. Verify before assuming:

git -C /path/to/repo ls-remote origin | wc -l

If that returns 0, the remote exists but is empty — nothing was ever pushed, and the local .git is the only copy in existence. Run git gc --prune=now to shrink it instead of deleting it.

The result

Working through this on one 512 GB MacBook Pro took it from 20 GB free to 215 GB free, without deleting a single irreplaceable file. If you would rather not do it by hand, Dustloft automates exactly these steps and refuses, in code, to touch anything on the list above.

See exactly what is on your own disk

Dustloft measures every real consumer of space on your Mac and shows each item with its full path and size before anything is removed. Free, open source, no subscription.

Install Dustloft

Two related references: whether clearing ~/Library/Caches is worth it, and the full list of locations Dustloft refuses to touch.