A 20 GB VPS disk fills up faster than most people expect. One day df -h shows 100%, apt refuses to install updates, MySQL stops writing, and your site returns 500 errors. The fix is almost never “upgrade to a bigger plan” — it is finding the forgotten log files, orphaned Docker layers, and oversized package caches that are eating your storage. These five commands cover the full forensic routine, from the initial panic to long-term prevention.
Before you start, compare VPS plans on our comparison table to see which providers offer NVMe storage with honest disk I/O guarantees — the right hardware makes a big difference when you are running low on space.
Command 1: Find the Biggest Space Consumers
Start with du to find directories that are eating the most space. The key is to stay on one filesystem so you do not count mounted volumes multiple times:
# Find the top 20 directories by size on the root filesystem only
sudo du -xhd1 / | sort -hr | head -20
# Drill into the top offender
sudo du -xhd1 /var | sort -hr | head -10
This usually reveals the usual suspects: /var/log, /var/cache/apt, /var/lib/docker, and /tmp. If you see a directory you do not recognize, investigate before deleting.
Command 2: Check for Inode Exhaustion
Sometimes df -h shows free space but your applications still cannot write files. This is inode exhaustion — the filesystem has run out of index nodes to track new files, even though space exists on the disk:
# Compare disk usage vs inode usage
df -h /
df -i /
If df -i shows 100% but df -h shows free space, you have inode exhaustion. The usual culprits are directories with millions of tiny files:
- PHP session files:
/var/lib/php/sessions— clear withsudo find /var/lib/php/sessions -type f -cmin +1440 -delete - Mail spools:
/var/mailor/var/spool/mail— check withls -l /var/mail - Docker overlay filesystems:
/var/lib/docker/overlay2— rundocker system prune - Systemd journal logs:
/var/log/journal— limit withjournalctl --vacuum-time=7d
Command 3: Find Deleted Files Still Held Open
A process (commonly a logging daemon, database, or web server) may keep a file descriptor open after the file has been deleted. The kernel does not release the disk blocks until the file descriptor is closed. This is one of the most confusing disk space problems because du shows the file is gone but df still reports 100% usage:
# List deleted files that are still held open
sudo lsof +L1 | head -30
The output shows the process name, PID, and the size of the deleted file. Restart the owning process to release the space — do not just kill the PID without understanding what it is. For example, if Nginx is holding a deleted log file: sudo systemctl restart nginx.
Command 4: Clean Package Manager Cache and Old Kernels
Package managers cache downloaded packages indefinitely. On a server that has been running for months, this can add up to 1–3 GB of unnecessary data:
# Ubuntu/Debian — check cache size first
du -sh /var/cache/apt
# Clean all cached packages
sudo apt clean
# Remove old kernels (keep the current one + 1 backup)
sudo apt autoremove --purge -y
# RHEL/Rocky/Alma
sudo dnf clean all
# Remove old kernels (keep the 2 most recent)
sudo dnf remove --oldinstallonly --setopt installonly_limit=2 -y
Old kernels are the single biggest reclaimable space on most VPS images. Each kernel image is 200–500 MB, and after a few updates, you can reclaim 1–2 GB just by removing obsolete kernels.
Command 5: Find and Compress Oversized Log Files
Log files that grow unbounded are the most common cause of disk-full alerts. Find the biggest log files and set up log rotation:
# Find log files larger than 100 MB
sudo find /var/log -type f -size +100M -exec ls -lh {} \;
# Check current logrotate configuration
cat /etc/logrotate.conf | head -30
# For Nginx access logs, add a logrotate entry:
# /etc/logrotate.d/nginx
# /var/log/nginx/*.log {
# daily
# rotate 7
# compress
# delaycompress
# missingok
# notifempty
# postrotate
# systemctl reload nginx > /dev/null
# endscript
# }
Summary: How Much Can You Reclaim?
| Source | Typical reclaimable space | Command |
|---|---|---|
| Old kernels | 500 MB – 2 GB | apt autoremove --purge |
| Package cache | 200 MB – 1 GB | apt clean |
| Uncompressed logs | 100 MB – 3 GB | logrotate + journalctl --vacuum-time |
| Docker dangling images | 500 MB – 5 GB | docker system prune |
| PHP session files | 50 MB – 500 MB | find ... -delete |
| Deleted open files | 100 MB – 2 GB | lsof +L1 + restart process |
Run these five commands quarterly and you will almost never hit a disk-full emergency. If you are consistently running out of space despite cleaning regularly, browse our VPS provider comparison to find a plan with larger NVMe storage at a reasonable price. For most workloads, 40 GB is the sweet spot — enough for the OS, applications, logs, and a few Docker images with room to spare.
Finally, set up a weekly cron job to alert you when disk usage passes 80%:
# Add to crontab -e
# Check disk usage every Monday at 6 AM
0 6 * * 1 df -h / | awk 'NR==2 {gsub(/%/,"",$5); if ($5 > 80) print "Disk usage: " $5 "%" | "mail -s "Disk Alert" [email protected]"}'
That cron job costs nothing to run and saves you from the 2 AM panic call when the disk fills up. For more VPS administration guides, compare VPS plans side by side on our comparison table.




Leave a Reply
You must be logged in to post a comment.