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 withsudo).
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 -lbut 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/databefore a disk was mounted there is invisible toduwhile 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.