TechX

Find where your disk space went, without installing a cleaner app

A full audit of a 350 GB home folder took 35.93 seconds with tools already on the machine. Here is the order to run them in, and why the first command most people try is the wrong one.

Tested on MacBook Pro (Mac16,8) · Apple M4 Pro · macOS 26.3.1 (25D771280a) · July 2026

Auditing a 350 GB home folder took 35.93 seconds on this machine. The checks that should come first, and that often make the audit unnecessary, took 0.17 seconds. Running them in the wrong order is the main reason this task feels slow.

0.17 s
Volume check n=1 df, tmutil listlocalsnapshots and diskutil info in sequence

Step 1: ask the volume, not the files

df -h /System/Volumes/Data
tmutil listlocalsnapshots /
diskutil info /System/Volumes/Data | grep -iE "container free|volume used"

Three commands, 0.17 seconds total, and they answer the most common version of this question outright.

df gives you real used and available figures. tmutil listlocalsnapshots lists APFS local snapshots, which is the single most frequent cause of a disk that appears fuller than its files explain. Snapshots hold blocks from deleted files so that older states remain restorable, and they are reported as purgeable rather than used, which is why Finder arithmetic can look impossible.

If snapshots are listed and your disk is uncomfortably full, you have your answer and can stop here. macOS reclaims them automatically under pressure, and you can force it by disabling and re-enabling Time Machine.

On the test machine that command printed a header and nothing else, so there were no snapshots, and the space genuinely was in files.

Step 2: the top level only

du -h -d 1 ~ | sort -hr | head -12

35.93 seconds on 350 GB, and consistent: 35.87, 36.36 and 35.57 across three runs, a spread of 0.79 seconds.

350G	/Users/teja
 88G	/Users/teja/Desktop
 75G	/Users/teja/Library
 61G	/Users/teja/Parallels
 46G	/Users/teja/Movies
 32G	/Users/teja/Documents
35.93 s
Full audit n=3 ±0.40 s du -h -d 1 on a 350 GB home folder, mean of three runs

-d 1 limits the walk to one level. That is the whole trick: a full recursive listing of a home folder produces tens of thousands of lines and takes considerably longer, and you almost never need it. Find the large directory first, then descend into it deliberately.

Desktop 88 GB Library 75 GB Parallels 61 GB Movies 46 GB Documents 32 GB
Top level of a 350 GB home folder, sorted. Two directories account for nearly half of it, which is the point of stopping at one level before descending.

sort -hr sorts human-readable sizes correctly, so 88G ranks above 900M. Without -h, sort compares the strings and puts 900M first.

The mistake that wastes a run

du -sh -d 1 ~        # wrong

On BSD du, -s and -d are mutually exclusive. -s wins, you get a single total, and nothing warns you that -d 1 was discarded. It returns fast enough to look like it worked.

Use -h -d 1 for a breakdown, or -sh for a single total. Never both.

Step 3: descend into the largest

du -h -d 1 ~/Library | sort -hr | head -10

Library is worth a look on almost any Mac, because several of its subdirectories grow without ever being visible in Finder: Caches, Containers, Application Support, Developer if you have Xcode, and Group Containers.

Repeat one level at a time. Each step is fast because you are walking a subtree rather than everything.

A caveat specific to APFS

du counts the blocks each file references. On APFS, cloned files share blocks, and shared blocks get counted once per file that points at them. A directory holding clones will be reported by du as substantially larger than the space it actually occupies.

The effect is easy to demonstrate: three clones of a 2 GiB file consume about 4 KiB of real disk between them, while du reports them as 6 GiB. Since Finder duplication produces clones, and several backup and virtualisation tools use them deliberately, this is not an edge case.

When du and df disagree, df is the one that matches what you can still write.

What to do about the results

Nothing here deletes anything, which is the point. Once you know where the space went, the decisions are ordinary: archive the video files, remove the virtual machine images you no longer boot, empty caches you can afford to rebuild.

Two directories deserve caution. Do not delete things from ~/Library unless you know what owns them; caches are usually safe and application data usually is not. And do not remove local snapshots by hand when the system reclaims them automatically under pressure.

The whole procedure

# 0.17 s — often sufficient on its own
df -h /System/Volumes/Data
tmutil listlocalsnapshots /

# ~36 s on 350 GB
du -h -d 1 ~ | sort -hr | head -12

# then descend, one level at a time
du -h -d 1 ~/Library | sort -hr | head -10

Two of those commands are effectively instant and the third scales with how much data you have. Running them in this order means you frequently never reach the slow one.

The directories worth knowing about

Two locations account for most of the space people cannot explain, and neither is visible in Finder without deliberately going looking.

~/Library is hidden by default and routinely holds tens of gigabytes. Within it:

du -h -d 1 ~/Library | sort -hr | head -10

Caches is safe to clear and will rebuild, at the cost of some slower first launches. Containers and Group Containers hold sandboxed application data and are not safe to clear; deleting a container discards that application’s documents and settings. Application Support is a mix of both and needs to be examined per application rather than as a block. Developer appears if Xcode is installed and can reach tens of gigabytes on its own, largely in DerivedData and device support files, both of which regenerate.

The system volume is the other one, and it is worth understanding rather than investigating:

df -h / /System/Volumes/Data

The read-only system volume shows about 12 GiB used on this machine and is not something you can or should reduce. Every figure worth acting on is on the Data volume.

When the numbers still do not add up

If files account for far less than df reports as used, three causes cover almost every case.

Local snapshots, which is the most common by a wide margin and which the first command in this article already checked.

Purgeable space, which macOS reports as available but which is currently occupied by content it can reclaim under pressure: snapshot data, cached files from iCloud Drive, and Photos content already uploaded. diskutil reports it separately from df:

diskutil info /System/Volumes/Data | grep -iE "container free|volume free"

A gap between those two figures is purgeable space, and it disappears on its own when something needs it rather than requiring intervention.

Cloned files, which cause the opposite error: du reports more than is actually consumed because shared blocks are counted once per file referencing them. When du and df disagree in that direction, df is correct.

A note on cleaner applications

The reason this article exists without recommending one is not ideology. It is that the information these commands produce is the same information a cleaner presents, and the decision about what to remove is the part that actually matters and the part a tool cannot make for you.

A cleaner that offers to free 40 GB is usually counting caches that would have been reclaimed automatically, plus some content you did want. Running du yourself takes about a minute, costs nothing, and produces a list you can act on with full knowledge of what each line is.

The one-command version

Once the order makes sense, the whole audit collapses into a function worth keeping:

diskaudit() {
  echo "=== volume ==="
  df -h /System/Volumes/Data | tail -1
  echo "=== local snapshots ==="
  tmutil listlocalsnapshots / | tail -n +2 | wc -l | xargs echo "count:"
  echo "=== purgeable gap ==="
  diskutil info /System/Volumes/Data | grep -iE "container free|volume free"
  echo "=== home, top level ==="
  du -h -d 1 ~ 2>/dev/null | sort -hr | head -12
}

The first three sections return in well under a second and frequently make the fourth unnecessary. The fourth takes about thirty-six seconds on 350 GB, which is worth knowing before you run it rather than after.

Takeaways

  • Volume-level checks take 0.17 seconds and often answer the question, so run them before any directory walk.
  • A full top-level audit of a 350 GB home folder took 35.93 seconds, consistent to within 0.8 seconds across three runs.
  • du -s and du -d are mutually exclusive on BSD du, and combining them silently returns the wrong thing.
  • du overstates usage on APFS whenever cloned files are involved, because shared blocks are counted once per file.

Questions

Why not just use a cleaner app?
The tools below report what is there without deciding anything for you, which is the part that matters when you are about to delete something. They also cost nothing and cannot remove a file you needed.
Why did my du command return instantly with one wrong number?
You probably combined -s and -d. On BSD du they conflict, -s wins, and you get a single summary line rather than the per-directory breakdown you asked for.
Do I need sudo?
Not for your own home folder. You do for system paths such as the Spotlight index, which is root-owned and refuses unprivileged reads.

Sources

What we read. Distinct from what we measured, which is in the article itself.

About the author

Teja Pagidimarri

11+ years in content marketing and SEO, based in Hyderabad, India. Every measurement published on TechX was taken by hand on the hardware listed in how we test.