df tells you how full a filesystem is; du (disk usage) tells you what is using the space. When a disk fills up, du is how you find the culprit.

Basic usage

du -sh /var/www          # total for one directory
du -sh *                 # each item in the current directory
du -sh /var/* 2>/dev/null
  • -s — summary: one total per argument instead of every subdirectory.
  • -h — human-readable sizes (K, M, G).
  • 2>/dev/null — hide “Permission denied” messages (or run with sudo).

Limit the depth

du -h --max-depth=1 /var
du -h -d 2 /home         # short form

Shows each subdirectory down to the given level — a good overview without thousands of lines.

Sort by size

du -h --max-depth=1 /var | sort -h
du -sh /var/* 2>/dev/null | sort -h | tail -10    # 10 largest

sort -h understands human-readable units (so 2G sorts above 900M). The largest items appear at the end.

Drill down step by step: find the biggest directory under /, then the biggest under that, and so on:

sudo du -xh -d 1 / 2>/dev/null | sort -h | tail
sudo du -xh -d 1 /var 2>/dev/null | sort -h | tail
sudo du -xh -d 1 /var/lib 2>/dev/null | sort -h | tail

-x keeps du on one filesystem, so it doesn’t wander into /proc, mounted backups or network shares.

Exclude paths

du -sh --exclude='node_modules' ~/projects
du -sh --exclude='*.log' /var/www

Files, not just directories

du -ah /var/log | sort -h | tail -20     # -a includes files

For finding individual large files anywhere, find is usually better — see find large files on Linux.

Totals

du -ch /var/log/*.log | tail -1          # -c adds a grand total

Apparent size vs disk usage

du reports space actually allocated on disk. That can differ from the file size:

  • Sparse files (VM images, some databases) look huge with ls -l but use little space.
  • Small files occupy at least one block (usually 4 KB).
  • Compressed filesystems (Btrfs, ZFS) allocate less than the logical size.

Show logical sizes instead:

du -sh --apparent-size /var/lib/libvirt/images

Inodes instead of bytes

A disk can be “full” with plenty of bytes free if it runs out of inodes (millions of tiny files — sessions, cache, mail queues). Count files per directory:

du --inodes -d 1 /var 2>/dev/null | sort -n | tail

See inode usage full.

ncdu: interactive and faster to navigate

sudo apt install ncdu
sudo ncdu -x /

ncdu scans once, then lets you browse directories sorted by size with the arrow keys — and delete with d. It’s the most convenient way to clean up a full disk.

Why du and df disagree

If df says the disk is 95% full but du adds up to much less, common reasons are:

  • Deleted files still open — a process holds a deleted log file open, so the space isn’t freed until the process restarts. Find them with sudo lsof +L1. See disk full troubleshooting.
  • Files hidden under a mount point — data written to /mnt/data before a disk was mounted there is invisible to du while the mount is active.
  • Reserved blocks — ext4 reserves 5% for root by default.
  • Snapshots on Btrfs/ZFS/LVM.

Typical space hogs on servers

Path Usual cause
/var/log Unrotated logs, verbose apps — see logrotate
/var/lib/docker Images, build cache, container logs — see docker prune
/var/lib/mysql, /var/lib/postgresql Database growth, binary logs
/var/cache/apt Package cache — sudo apt clean
/home/*, /root Forgotten backups and downloads
/tmp, /var/tmp Temporary files never cleaned
/var/log/journal systemd journal — sudo journalctl --vacuum-size=500M

Quick reference

Task Command
Size of a directory du -sh DIR
Sizes of items here du -sh *
One level deep, sorted du -h -d 1 DIR | sort -h
Stay on one filesystem -x
Exclude --exclude=PATTERN
Logical size --apparent-size
Inode counts du --inodes
Interactive ncdu -x DIR

Related: df command. If your data has simply outgrown the disk, a Storage VPS gives you hundreds of gigabytes of SSD.

  • Linux
  • Disk Space
  • Command Line