How do I check System Data size on a Mac from the Terminal?

How to check System Data size on Mac Terminal with df, diskutil, and a du audit that names every folder feeding the gray bar. Read-only, safe, no cleaner installed.

8 min read · Published · Updated · Saad Belfqih

You open System Settings, click Storage, and the gray bar says System Data 168 GB. You want the same number in a Terminal window so you can grep it, log it, or diff it against yesterday. You type df -h / and get total used and free, but no line labelled System Data. There is a reason for that. macOS computes System Data as a residual, not as a directly measured category. This post walks the exact commands to check System Data size on Mac Terminal, plus the folder-level audit that tells you what is actually inside the bar.

TL;DR
To check System Data size on Mac Terminal, start with `df -h /` for the total used, then use `diskutil apfs list` to subtract the sibling categories macOS reports separately. Follow with a `du -sh` audit of the 15 developer paths that live under System Data (Xcode, CoreSimulator, Claude Code, Cursor, Codex, Ollama, Docker.raw, APFS snapshots). CleanMyDev runs the same audit in one click and Moves to Trash so a wrong call survives a seven-day undo window.

Why is there no single Terminal command that returns System Data?

Apple's Storage bar queries the six real categories (macOS, Applications, Documents, Photos, Mail, Messages) and prints the shortfall as System Data. That is why System Data can jump 40 GB overnight without any file arriving in a documented category. It is the leftover bucket by design.

The consequence for Terminal is simple: no command in stat, df, or du returns System Data directly. You reconstruct it. The reconstruction is short and it reveals which folder inside System Data is the actual culprit.

What does df -h / tell me about System Data?

df -h / shows disk-level totals for the root APFS volume. It is the first line of any Terminal check.

df -h /

A typical dev MacBook returns something close to this:

Filesystem      Size    Used   Avail Capacity  iused ifree %iused  Mounted on
/dev/disk3s1s1  926Gi   612Gi  283Gi    69%   4.2M  2.9G    0%   /

612 Gi used is a real, measured number. It matches the "Used" total in System Settings within a few hundred MB. What df does not do is split that 612 Gi into categories. For that, you either check System Settings or you run the folder audit below. Consider df -h / your baseline.

How do I list APFS containers and snapshots from Terminal?

APFS snapshots can hide 5 to 40 GB inside System Data on their own. diskutil prints them.

diskutil apfs list

Scroll to your synthesised volume group and you get lines like:

Container disk3
+-- Volume disk3s1
    Snapshot 1:  com.apple.TimeMachine.2026-07-01-183042.local
    Snapshot 2:  com.apple.TimeMachine.2026-07-02-091502.local

Each local Time Machine snapshot pins the blocks that existed at snapshot time even after you delete the files. tmutil listlocalsnapshots / prints the same list with dates, and sudo tmutil deletelocalsnapshots <date> removes one. Snapshots are frequently the reason a 40 GB Xcode delete only frees 8 GB on the bar until the next hour.

What is the read-only Terminal audit for System Data?

The audit below runs du -sh on every folder macOS files under System Data on a developer Mac. It is one shell block, safe to paste, and it writes the output to your Desktop so you can diff it against next month's run.

# Read-only System Data audit for a developer Mac.
# Nothing gets deleted. Nothing gets moved. Safe with builds running.
{
  printf "\n=== Disk baseline ===\n"
  df -h /

  printf "\n=== Xcode + iOS dev (usually the biggest hidden slice) ===\n"
  du -sh ~/Library/Developer/Xcode/DerivedData 2>/dev/null
  du -sh ~/Library/Developer/Xcode/Archives 2>/dev/null
  du -sh ~/Library/Developer/Xcode/"iOS DeviceSupport" 2>/dev/null
  du -sh ~/Library/Developer/Xcode/"watchOS DeviceSupport" 2>/dev/null
  du -sh ~/Library/Developer/CoreSimulator/Devices 2>/dev/null
  du -sh ~/Library/Developer/CoreSimulator/Caches 2>/dev/null
  du -sh ~/Library/Developer/XCTestDevices 2>/dev/null

  printf "\n=== AI coding tools (fastest growing category in 2026) ===\n"
  du -sh ~/.claude 2>/dev/null
  du -sh ~/Library/Caches/claude-cli-nodejs 2>/dev/null
  du -sh ~/.codex 2>/dev/null
  du -sh ~/Library/Application\ Support/Cursor 2>/dev/null

  printf "\n=== Local LLMs and models ===\n"
  du -sh ~/.ollama/models 2>/dev/null
  du -sh ~/.cache/huggingface 2>/dev/null
  du -sh ~/.lmstudio/models 2>/dev/null

  printf "\n=== Containers and JS ===\n"
  du -sh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw 2>/dev/null
  du -sh ~/.npm/_cacache 2>/dev/null

  printf "\n=== APFS snapshots (hidden inside System Data) ===\n"
  tmutil listlocalsnapshots / 2>/dev/null

  printf "\n=== Orphaned simulator runtimes (needs sudo) ===\n"
  sudo du -sh /System/Library/AssetsV2/com_apple_MobileAsset_iOSSimulatorRuntime 2>/dev/null
} | tee ~/Desktop/system-data-audit-$(date +%Y%m%d).txt

The last line writes a dated file to your Desktop. Rerun the same block in a month and diff the two files to see exactly which subsystem grew.

How do the Terminal numbers map to the Storage bar categories?

The macOS Storage bar files each folder under a category using a hardcoded path-to-label map. Here is the mapping for the paths above.

Terminal path macOS Storage category Owning tool
~/Library/Developer/Xcode/DerivedData System Data Xcode
~/Library/Developer/Xcode/Archives System Data Xcode
~/Library/Developer/CoreSimulator System Data Xcode
~/Library/Developer/XCTestDevices System Data Xcode
~/.claude System Data Claude Code
~/Library/Caches/claude-cli-nodejs System Data Claude Code
~/.codex System Data Codex CLI
~/Library/Application Support/Cursor System Data Cursor
~/.ollama/models System Data Ollama
~/.cache/huggingface System Data Hugging Face
~/Library/Containers/com.docker.docker/.../Docker.raw System Data Docker Desktop
APFS local snapshots System Data macOS
/System/Library/AssetsV2/...iOSSimulatorRuntime System Data Xcode + macOS
/Applications/Xcode.app Applications (not System Data) Xcode
~/Documents/* Documents (not System Data) User

Everything in the first block is System Data by classification. The Storage bar counts them together and gives them a single label. The Terminal audit gives them individual names.

Which paths usually dominate System Data on a dev Mac?

The brtkwr.com writeup on using Claude to free 200 GB documents the actual ranking on one dev's Mac after a full audit. The verbatim finding:

"Docker was the biggest culprit... The volumes were almost entirely unused, probably from old postgres/redis containers I'd stopped months ago."

That matches what the audit above tends to print on a working iOS + AI dev Mac in 2026: Docker.raw first, DerivedData second, Claude Code third, iOS DeviceSupport fourth. The three or four biggest lines usually account for 60 to 80 percent of the System Data bar. Everything else is noise, though noise still adds up.

The Claude Code 472 GB issue #18869 is the extreme case where a single tool ran away with the whole disk:

"I used DaisyDisk to dig into the issue and discovered folders taking up 472GB, both related to Claude CLI."

The Terminal audit catches that class of bug in the AI coding tools block, without needing DaisyDisk or any GUI tool at all.

How do I check just the System Data number, ignoring folders?

If you only want the residual number, compute it yourself. There is no built-in shortcut, but the arithmetic is short.

# Rough System Data estimate from Terminal.
USED_KB=$(df -k / | tail -1 | awk '{print $3}')
APPS_KB=$(du -sk /Applications 2>/dev/null | awk '{print $1}')
DOCS_KB=$(du -sk ~/Documents ~/Downloads ~/Desktop 2>/dev/null | awk '{sum += $1} END {print sum}')
PHOTOS_KB=$(du -sk ~/Pictures/Photos\ Library.photoslibrary 2>/dev/null | awk '{print $1}')
# System Data is the residual after apps + docs + photos + iCloud sync (rough).
SYSDATA_KB=$(( USED_KB - APPS_KB - DOCS_KB - PHOTOS_KB ))
printf "Estimated System Data: %.1f GB\n" "$(echo "$SYSDATA_KB / 1024 / 1024" | bc -l)"

The output is an estimate, not a match to the pixel on the Storage bar. Expect it within 5 to 15 percent. Use it for month-over-month tracking, not to argue with Apple.

Why is my Terminal total different from System Settings?

Three reasons. APFS clones share blocks, but du -sh counts each reference as full size, so two 4 GB clones of the same base image look like 8 GB to du and 4 GB on disk. Xcode simulators clone runtime images aggressively, which is why du -sh ~/Library/Developer/CoreSimulator/Devices often reports more than you actually reclaim.

APFS snapshots pin blocks. If a snapshot captured a file you deleted, the blocks stay on disk, df sees them, and the Storage bar files them under System Data. Third, the Storage bar reads a background index that updates every few minutes, so df moves before the bar does. Give it 60 to 120 seconds before comparing.

What do I do after the audit prints the culprits?

Nothing yet. The audit is read-only for a reason. Look at the numbers, decide what is safe to reclaim, then use the per-folder guides. The reduce System Data macOS safely playbook walks the nine reversible folders in the safest order, and decoding System Data categories explains what each bucket contains. If Docker is your top line, docker system prune -a --volumes is the official knob, but read docker system prune explained first because the flag deletes more than most devs expect.

All safe follow-ups move to ~/.Trash with a timestamped folder name so you can restore inside seven days if a build breaks.

When should I automate the audit?

Run it once, look at the numbers, then decide. If System Data grows by more than 20 GB per week, a monthly cron running the block into a dated file gives you a paper trail. Diff last month against this month to spot the leaking subsystem. If the growth is one-off because you started using Claude Code and Docker heavily this year, the audit is a one-off too.

CleanMyDev automates the same audit end-to-end across 110+ developer-specific paths, prints per-row sizes with last-modified dates and risk labels, and Moves to Trash so a wrong call survives seven days. The lifetime license is $9.99 at /#pricing. Audit mode is free so you can compare it against the Terminal output before paying.

Related reading

Stop wondering what System Data is.

CleanMyDev opens the box. 110+ developer-specific cleanup targets. Move-to-Trash by default. $9.99 lifetime.

Get CleanMyDev — $9.99