It’s 2 AM. You get paged. A service just crashed because /var is 100% full. Your stomach drops.
Running out of disk space is one of those problems that sneaks up on you. One day you’ve got 20% free, the next you’re scrambling to find what’s hoarding all 500 GB. The annoying part? The standard tools lie to you, hide things in weird places, or take forever to report anything useful.
Here’s your survival guide to finding (and killing) space hogs before that 3 AM page becomes a 4 AM postmortem.
Start with the Overview: df -h
First, get the big picture:
$ df -hFilesystem Size Used Avail Use% Mounted on/dev/sda1 100G 95G 2.3G 98% /tmpfs 16G 0 16G 0% /dev/shm/dev/sdb1 500G 480G 12G 98% /datadf -h shows you which mountpoint is actually full. It’s quick, it’s honest, and it tells you how much runway you have left. In the example above, both / and /data are gasping for air.
If your root filesystem is full but /data has breathing room, you might be able to move stuff around. If both are toast, you’re in fire-fighting mode.
Find the Top-Level Culprits: du -sh
Now drill down. Check what’s eating space at the root level:
$ du -sh /*1.2G /bin8.3G /boot2.4G /etc14G /home1.1G /lib112G /opt5.6G /srv42G /var6.2G /usrThe -s flag gives you a summary (one line per directory), and -h makes it human-readable. This immediately shows you that /var and /opt are the real estate hogs. Now you know where to aim.
The Heavy Hitter: du -sh * | sort -hr | head -20
For a more detailed breakdown within a problem directory, sort by size:
$ cd /var && du -sh * | sort -hr | head -2038G log2.1G lib1.3G cache800M tmpThis finds the 20 biggest items in the directory and sorts them descending. Instant clarity. In this case, /var/log is hoarding 38 GB of old logs. That’s your target.
The Interactive Solution: ncdu
If you like poking around interactively instead of typing commands over and over, install ncdu:
sudo apt install ncduncdu /varIt’s a curses-based disk usage explorer. Navigate with arrow keys, press d to delete, r to refresh. It’s the closest thing to a GUI disk analyzer on Linux, and it’s blazingly fast even on large directories.
Find Specific Offenders: find
Sometimes you need to hunt by file type or age, not just directory. Find the 20 biggest files on your system:
find / -type f -exec du -h {} + 2>/dev/null | sort -hr | head -20Or find .log files larger than 1 GB:
find / -name "*.log" -size +1G -exec ls -lh {} \;Or find files older than 30 days (archive or delete them):
find /var/log -type f -mtime +30 -deleteThe Usual Suspects
Here’s where that space actually goes, and how to reclaim it without nuking production:
/var/log — Old Log Files
Logs pile up. PostgreSQL, nginx, systemd, Docker — they all write relentlessly.
du -sh /var/log/*sudo journalctl --vacuum-size=500M # Keep only last 500 MB of systemd logssudo find /var/log -name "*.gz" -mtime +30 -delete # Old compressed logssudo find /var/log -name "*.log" -mtime +7 -delete # Uncompressed logs > 7 daysDocker Images, Layers, and Dangling Data
Docker can silently accumulate hundreds of GB. Unused images, stopped container filesystems, build cache — it all adds up.
docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}" | sort -k2 -hrdocker system prune -a # Delete unused images, containers, networksdocker image prune -a --filter "until=720h" # Remove images not used in 30 daysdocker volume prune # Remove orphaned volumesOld Kernel Versions in /boot
Every kernel upgrade leaves the old one behind. Most systems only boot one kernel.
du -sh /boot/*sudo apt autoremove --purge # Remove old kernel packagessudo apt clean # Clean package cachePackage Manager Caches
apt keeps downloaded .deb files around. You can safely purge them:
sudo apt clean # Full cleanupsudo apt autoclean # Conservative cleanup (older caches)For Arch/Pacman:
sudo pacman -Sc # Clean all uninstalled packagessudo pacman -Scc # Clean all cache (more aggressive)Core Dumps
If a process crashes hard, the kernel drops a multi-GB core dump. Disable them or clean them up:
find /var/lib/systemd/coredump -type f -deleteecho "kernel.core_pattern=/dev/null" | sudo tee -a /etc/sysctl.conf && sudo sysctl -pTemporary Files Rotting in /tmp
Old temp files can linger for months:
du -sh /tmp/*sudo find /tmp -type f -mtime +30 -deleteThe 3 AM Checklist
When / hits 98% and you need to free space right now:
- Kill the logs —
sudo journalctl --vacuum-size=200M(instant 2–5 GB often) - Docker prune —
docker system prune -a(can free 10–50 GB) - Clean package cache —
sudo apt clean(another 1–5 GB) - Find and move large files — Use
du -shto find outliers you can archive - Temp file purge —
sudo find /tmp -type f -delete - Review
/var/log— Archive or compress old logs, disable verbose logging if needed
In 80% of cases, one of the first three solves the problem. If you’re still full, you’ve got a legitimate space crunch — time to either add a disk or do real archival work.
Prevention: Set Log Rotation and Limits
Once you’ve freed space, keep it from piling up again:
/var/log/myapp.log { daily rotate 7 compress delaycompress notifempty create 0640 www-data www-data}For systemd journal:
SystemMaxUse=500MMaxFileSec=7dayRestart the service and logs stay under control without manual intervention.
Running out of disk space sucks, but it’s solvable. Keep du, df, and ncdu in your mental toolbox. Automate log rotation. And if you’re running Docker, get aggressive with docker system prune monthly.
Your 3 AM self will thank you.