Check disk space from the Terminal on a Mac with df and du
· 6 min read
Two commands do the job. df -h /System/Volumes/Data tells you how full the disk is, and du -hd 1 ~ | sort -h tells you which folders are using the space, largest last. If du prints Operation not permitted, macOS privacy protection is keeping Terminal out of certain folders, and the fix is a setting, not sudo.
How full is the disk: df
Open Terminal from Applications, Utilities, and run:
df -h /System/Volumes/Data
The -h flag prints sizes in gigabytes instead of blocks. The line shows Size, Used, Avail and Capacity for the volume that holds your files.
Why that path rather than /? Since macOS Catalina, the startup disk is split into a sealed, read-only system volume and a separate data volume, and everything you create lives on the data volume. df -h / reports the system volume, whose Used figure covers only macOS itself. Its Avail figure matches, because both volumes draw on the same pool of free space, which is exactly what makes the output confusing at a glance.
Run df -h on its own to list every mounted volume, including external drives. Lines starting with devfs or map are system plumbing and can be ignored.
One caveat: Avail often differs from the free space System Settings shows, because System Settings counts purgeable space (things macOS can delete on demand) as available. df’s figure is what apps can use right now. Purgeable space on a Mac explains the gap.
What is using it: du
du walks through folders and adds up file sizes. The most useful form lists each folder one level down, sorted by size:
du -hd 1 ~ 2>/dev/null | sort -h
-hprints human-readable sizes.-d 1stops one level deep: each folder in your home, then a total.2>/dev/nullhides error messages, which are covered below.sort -hsorts sizes like 900M and 2.1G correctly, so the largest land at the bottom.
Then drill into whatever is biggest, for example du -hd 1 ~/Library 2>/dev/null | sort -h, and keep going until the culprit is obvious. For a single folder’s total, du -sh ~/Movies is enough.
To measure the whole data volume, including other accounts and shared folders, add sudo and -x so du stays on that one volume:
sudo du -xhd 1 /System/Volumes/Data 2>/dev/null | sort -h
This can take several minutes on a full disk. sudo asks for your admin password, and nothing appears on screen as you type it.
Why du says Operation not permitted
Run du across your home folder without 2>/dev/null and you will see lines like this:
du: /Users/you/Library/Mail: Operation not permitted
This is not an ordinary file permission problem, and sudo does not fix it. macOS privacy protection keeps apps, Terminal included, out of certain locations until you grant access: Mail, Messages, Safari’s data and other apps’ private folders among them. Whatever du cannot read is quietly left out of its totals, so the numbers can come out well below what the disk really holds.
To let Terminal in:
- Open System Settings, Privacy & Security, Full Disk Access.
- Turn on the switch for Terminal. If it is not listed, click the add button, go to Applications, Utilities, and choose Terminal.
- Quit Terminal and open it again. The new permission applies to new sessions only.
Full Disk Access is broad: every command you run in Terminal inherits it. Many people grant it for the audit and switch it off again afterwards. Full Disk Access on a Mac covers what it opens up.
When df and du disagree
Add up du’s folders, compare the result with df’s Used figure, and they rarely match. The usual reasons:
- Local snapshots. Time Machine keeps snapshots on the internal disk. Their space counts in df but sits in no folder du can see.
tmutil listlocalsnapshots /lists them. - APFS clones. When you duplicate a file, APFS can let the two copies share their data until one of them changes. du counts each copy in full; the disk stores the shared part once.
- Sparse files. Virtual machine disks and container images can report a large size while using much less.
du -Ashows the apparent size and plain du shows the space actually used, and the difference is the empty part. - Swap. It lives on its own volume,
/System/Volumes/VM, whichdf -hlists on a separate line. - Protected folders, if Terminal does not have Full Disk Access.
The Mac says storage is full, but the folders do not add up goes through each of these in more depth.
The same answer without the commands
The Terminal is precise, but it is slow reading when the answer is spread across twenty folders, snapshots and a swap volume. Crumb is a menu bar disk cleaner whose free audit covers the whole Mac, not just the home folder. It breaks System Data into its parts (caches, logs, swap, temporary files and leftovers), and shows Time Machine local snapshots, Docker.raw’s real versus apparent size, iOS backups, and which account on a shared Mac is using the space.
The audit is read-only, so it deletes nothing. If you then want to clear space, the free tier includes one full cleanup with the total shown before you commit, and $9 once unlocks everything on up to 2 Macs. It runs on macOS 12 Monterey or later. The commands above remain the way to double-check any number it shows you.
Questions
Why does du take so long? It reads the size of every file under the folder you give it, and a home folder with a large Photos library or a few code projects can hold a great many files. Point it at a narrower folder, or keep the depth at 1.
Is it safe to run du with sudo? Yes. du only reads; it never changes or deletes anything. sudo lets it into other accounts’ folders, but it still cannot get past privacy protection unless Terminal has Full Disk Access.
What is the difference between df and du? df asks the file system how much of a volume is used and free. du walks folders and adds up what it finds. df is the authority on free space; du tells you where the used space went.