Alright, let’s get our hands dirty and talk about figuring out where all your disk space went. You’ve seen the dreaded “No space left on device” error, or you’re just morbidly curious about what’s hoarding all those precious bytes. You have three main tools for this job: the old guard (df and du) and the brilliant new kid (ncdu). They answer related but fundamentally different questions. df tells you how full your filesystems are. du tells you how much space files and directories are consuming. Mixing them up is a classic rookie mistake, so let’s not be rookies.

df: The Big Picture View

Think of df (disk free) as your strategic overview map. It reports on the usage of mounted filesystems—your hard drives, partitions, network drives, and all that jazz. Its most important job is to answer: “Do I have space to write to this filesystem at all?”

Running it plain is helpful, but the default output is in clunky 1K blocks, which is what you and I think in when we’re from the 1970s. Use the -h flag for “human-readable” output (KiB, MiB, GiB), because we are, in fact, human.

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  468G  412G   33G  93% /
/dev/nvme0n1p1  511M  144M  368M  29% /boot

See that 93%? That’s your system gently clearing its throat before it has a full-blown panic attack. The Avail column is your critical number—that’s the space you, a mere user, can actually use. The Used number can be misleading due to reserved blocks (typically 5% for the root user, a sensible failsafe to keep the system running even when users fill it up).

Now, a pro tip: if you’re dealing with inodes (the data structures that track files), you can run out of them even if you have disk space left. It’s like a parking lot with empty spaces but no more tickets. It’s infuriating when it happens.

$ df -i
Filesystem       Inodes  IUsed   IFree IUse% Mounted on
/dev/nvme0n1p2  3.1M    2.9M    200K    94% /

If that IUse% hits 100%, you’re hosed, no matter what df -h says. It’s a rare but spectacular failure mode, often caused by a process spewing millions of tiny files.

du: The Ground-Level Recon

While df looks at the filesystem metadata, du (disk usage) does the grunt work of crawling through directories and adding up the sizes of all the files. Its question is: “What the hell is in this directory costing me all my space?”

Again, always use -h unless you enjoy mental arithmetic.

# How big is the current directory?
$ du -h
12G    ./Documents
250G   ./Videos
4.0K   ./Desktop
262G   .

# How big is a specific directory? Use -s for 'summary' to avoid a huge list.
$ du -sh /var/log
3.4G   /var/log

The classic pitfall here is permissions. du can only measure what you have permission to read. If you du -sh / and see a total that’s way smaller than what df reports, congratulations, you’ve just found files or directories owned by other users (often root) that you can’t access. You’ll need sudo to get the true, horrifying picture.

# This will probably give a much larger, more accurate number
$ sudo du -sh /

Another gotcha is that du reports file size, not disk usage. On filesystems with block allocation (like ext4), a 1-byte file still takes up a full block (typically 4KiB) on disk. du shows you the latter by default—the actual disk space consumed. Use the --apparent-size flag if you care about the literal file size instead. Almost always, you want the default behavior.

ncdu: du, But Actually Usable

Let’s be honest: du is a pain. You get a giant list, then you have to du -sh on a bunch of subdirectories to hunt down the culprit. It’s tedious. This is where ncdu (NCurses Disk Usage) enters, stage left, to save us all. It’s not always installed by default, but it’s worth its weight in gold. Install it (sudo apt install ncdu or brew install ncdu).

It does a du scan first, then presents you with a gorgeous, navigable TUI where you can sort directories by size by pressing ’s'.

# Scan the current directory
$ ncdu

# Scan a specific directory (like the root, which needs sudo)
$ sudo ncdu /

You’ll get an interface like this:

--- / ----------------------------------------------------------
  350.4 GiB [##########] /usr
  150.2 GiB [####      ] /home
    5.5 GiB [          ] /var

You use the arrow keys to dive in, and it’s instantly obvious where your space is going. It’s the fastest way to find that 200GB file of “downloads” you forgot about or the 50GB of Docker containers cluttering up /var/lib. It also handles permission issues gracefully by just showing you what it can. This tool is so good it feels like cheating. Use it.