MacDiskSleuth’s job is to answer two questions honestly on modern macOS:
APFS makes both questions harder than they look, and most tools answer them with numbers designed for a filesystem Apple retired in 2017. This document defines exactly what MacDiskSleuth’s numbers mean.
| Lens | Source | Meaning |
|---|---|---|
| Logical | ATTR_FILE_DATALENGTH |
What files claim to be. Matches ls -l and most tools. |
| Physical | ATTR_FILE_ALLOCSIZE, shared bytes counted once |
What the disk actually holds. |
| Freeable | ATTR_CMNEXT_PRIVATESIZE + group analysis |
What deleting the item frees right now. |
Why they diverge:
cp -c, and many app “Save As”
paths create files that share every block with their original. Logical counts
them twice; the disk stores them once. du double-counts clones.du handles these; naive scanners don’t.Docker.raw may claim 60 GB and occupy 12 GB./Applications and /System is
transparently compressed; logical exceeds physical, and that saving is real.Shared bytes are counted once, in the deepest folder that contains all files sharing them.
That single rule makes per-folder numbers deterministic and keeps every level of the tree self-consistent:
a/ and b/ contributes 10 MB to their common
parent’s physical size — not 20 MB — and its “freeable” appears only at that
parent, because deleting just a/ or just b/ frees nothing.Writing into a clone splits it from its APFS clone family (it gets a new clone ID) even though unwritten extents remain physically shared. macOS exposes no way to re-link those files. MacDiskSleuth handles this the only honest way:
PRIVATESIZE is the kernel’s own answer).macdisksleuth overview reconciles the numbers Finder, df, and Apple’s Storage
pane each report differently:
df doesn’t. Both are telling a partial truth.tmutil thinlocalsnapshots). macOS does not report per-snapshot sizes —
MacDiskSleuth says “unknown” rather than inventing a number. Whenever snapshots
exist, freeable numbers carry the caveat: freed space may appear gradually.ATTR_VOL_SPACEUSED, because statfs on
APFS reports container-wide totals for every volume in the container.overview --deep scans the major roots and names the
remainder — the bucket Apple’s Storage pane won’t itemize.getattrlistbulk(2) — bulk metadata, hundreds of entries
per syscall — with APFS extended attributes (PRIVATESIZE, CLONEID,
EXT_FLAGS, CLONE_REFCNT) riding along. A readdir+fstatat fallback
covers filesystems that refuse bulk reads; missing attributes degrade
the lenses gracefully (physical falls back to st_blocks)./ follows the firmlink map the way you think about your Mac:
/Users, /Applications etc. count at their visible locations; the literal
/System/Volumes/Data subtree is traversed only for content no firmlink
covers. A (device, inode) visited-set makes double-counting structurally
impossible.# make a clone and watch du lie:
dd if=/dev/urandom of=orig.bin bs=1m count=64
cp -c orig.bin clone.bin
du -sh . # ~128M — wrong
macdisksleuth scan . --depth 1 # physical ~64M — right
macdisksleuth info clone.bin # "Deleting frees ~0 B now"
The test suite builds real fixtures — clonefile(2), link(2), sparse files,
permission-denied directories — and asserts the engine’s numbers against the
kernel’s own (st_blocks, PRIVATESIZE) on every run.
macdisksleuth recommend (and the list after every scan) ranks what to delete
first. It inherits every rule above:
Staleness comes from ATTR_CMN_MODTIME, rolled up so every folder knows the
newest change anywhere inside it. The ranking applies it per member: a cache
folder always has something written today, but the parts nobody touched in a
year still earn full credit.