du / df, one lesson per page
Thirty lessons for reading disk space on a Linux system: the report/estimate split between df and du, the six columns of df output and -h versus -H, du's one-line-per-directory walk, -s and --max-depth, the named reasons the two numbers disagree (open deleted files, mounts shadowing directories, sparse files), du -h | sort -h hunting, and --inodes for the day the disk is full but the files are small.
A diagram, the map, and one thing to try this week. That's a page.
du / df, one lesson per page
Thirty lessons for reading disk space on a Linux system: the report/estimate split between df and du, the six columns of df output and -h versus -H, du's one-line-per-directory walk, -s and --max-depth, the named reasons the two numbers disagree (open deleted files, mounts shadowing directories, sparse files), du -h | sort -h hunting, and --inodes for the day the disk is full but the files are small.
Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).
Every fact in this book is as the official source states it, fetched and read during this build: the du(1) and df(1) manuals of GNU coreutils 9.4, the same manuals hosted by the Linux man-pages project at man7.org (the man7.org fetch from this datacenter timed out; the identical local system copies were cached and cross-checked against the live man7.org fetches). Demand evidence from live beginner threads, reconfirmed at dispatch; no facts are sourced from tutorials, howtogeek, linuxize, Reddit or StackExchange. An independent guide, not affiliated with or endorsed by the GNU project.
Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.
© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.
Edition 1.0 · stevehodgkiss.net
Contents
Per the du(1) and df(1) manuals of GNU coreutils 9.4: du is 'estimate file space usage' and 'summarize device usage of the set of FILEs, recursively for directories'; df is 'report file system space usage' and 'displays the amount of space available on the file system containing each file name argument'.
Report vs estimate
Two commands, one subject: how full the disk is. Per du(1), du estimates file space usage by walking your files and summing. Per df(1), df reports the space the file system itself says is used and available.
They measure different things, so their numbers can disagree while both are right. That disagreement has names, and the names have checks.
This book is the pair: the report, the estimate, and the gap between.
This week, run df -h and du -sh on your home directory and write down both numbers. If they differ, that difference is the rest of this book.
Per the df(1) manual's documented output: the default listing shows one row per file system with the file system name, its total 1K blocks, used, available, the used percentage, and the mount point.
Six columns
One row per mounted file system, six facts per row. In order: the file system's source device, its total blocks, how many are used, how many are available, the percentage used, and the mount point.
Read left to right: which disk, how big, how full, where it hangs on your tree. That is the whole report.
The percent column is the one you will check daily. The mount column is the one you will act on.
This week, run df -h and name each of the six columns out loud on one row. From then on you read it in one glance, not six.
Per du(1): -s or --summarize displays only a total for each argument. --max-depth=0 is the same as --summarize.
Just the total
The most-used du flag. Per du(1), -s or --summarize displays only a total for each argument: the whole recursive walk still happens, the output is one line.
du -sh ~ is the phrase: human units, one number, how big is home. The manual notes the exact twin: --max-depth=0 is the same as --summarize.
-s answers 'how big is this'. The next page answers 'which part of this'.
This week, replace every bare du with du -sh. One number per directory is a habit; walls are not.
Per du(1): du summarizes device usage of the set of FILEs, recursively for directories; with -x or --one-file-system it skips directories on different file systems. Per df(1): df displays one row per mounted file system; a file system mounted at a subdirectory shadows any files beneath it from a walk of the parent.
The mount shadow
Mount a fresh disk at /backup and the old files there do not vanish; the mount shadows them. A du walk of the parent follows into the mount and sums the new disk's bytes instead.
Per du(1), the fix is a flag: -x or --one-file-system skips directories on different file systems. One disk per sum, no shadows.
df never has this problem; it reports mounts directly. It is a du-side trap, with a du-side flag.
Run du -shx against du -sh on a directory that holds a mount this week (try / or /var). The difference is the shadow.
Per du(1): -h prints sizes in human readable format. Per the sort(1) manual of GNU coreutils 9.4: -h compares human readable numbers (e.g., 2K 1G); -r reverses the result of comparisons.
Rank the suspects
The one-line hunt: du -h | sort -h. Per the sort(1) manual of the same coreutils release, -h compares human readable numbers: 2K 1G sorts correctly, because it reads the unit letters.
The biggest lands last. Add -r to reverse, biggest first: du -h | sort -hr is the shape of every disk cleanup ever run.
Rank, do not scroll. The bottom of that list is your next three actions.
This week, run du -h in your biggest directory, pipe through sort -hr, and act on the top line only. One hunt, one deletion, done.
Per df(1): df reports space for each file system, or all mounted ones by default. Per du(1): du estimates recursively per argument, with -s to summarize, -d to cap depth, -x to stay on one file system, and -h for human units; sort(1) -h ranks the output. The gap between the two numbers has named causes: open deleted files, mount shadows, sparse files, and root's reserve.
One habit to keep
The whole book in one loop. df -h: which file system is full. du -h -d 1, then sort -hr: what is inside it. When the numbers disagree, name the gap: a held deleted file, a mount shadow, sparse files, root's reserve.
Report vs estimate. Both are right. The name of the gap is the difference between a guess and a diagnosis.
Two commands, four names, one loop. That is disk space, handled.
Teach the loop to someone this week: df to find the disk, du to find the directory, name the gap before deleting. If you can teach it, it is yours.