What to do when a Linux VPS disk is full
Recover space safely, find deleted-but-open files, identify runaway logs and Docker layers, then prevent the same disk incident from returning.

A full root filesystem causes strange failures: databases stop writing, SSH logins hang, package installs break, and applications report unrelated errors. The priority is to create a little safe working space, then find the actual owner.
Confirm which resource is exhausted
df -hT
df -ih
The first command checks bytes; the second checks inodes. Millions of tiny files can exhaust inodes while gigabytes remain free.
Create breathing room
Vacuum old journal data and clear package downloads:
sudo journalctl --vacuum-size=200M
sudo apt clean
Avoid deleting unfamiliar files under /var/lib. Database and container directories are not caches.
Find the largest directories
Stay on the root filesystem with -x:
sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo find /var/log -type f -size +100M -printf '%s %p\n' | sort -n
Walk down the largest path. A suddenly huge log usually indicates a retry loop or debug mode, not merely missing rotation.
Find deleted files still using space
Deleting a file does not free its blocks while a process still has it open:
sudo lsof +L1
Restart or gracefully reload the owning service. Do not reboot blindly if the full disk has left a database requiring recovery.
Check Docker separately
docker system df
docker ps --size
sudo du -sh /var/lib/docker/* 2>/dev/null
Remove only resources you recognise. docker image prune removes dangling images; docker builder prune removes build cache. Avoid docker system prune --volumes on a production server unless you have reviewed every volume.
Container JSON logs can grow without limits. Add log rotation in Compose or Docker daemon configuration.
Recover and verify services
After freeing space:
df -h /
systemctl --failed
journalctl -p err --since '30 minutes ago'
Check database integrity and application health. Some services do not resume automatically after an ENOSPC error.
Prevent recurrence
Alert at 80% and 90% usage, but also alert on growth rate. Cap journald and container logs, set retention for backups, and keep user uploads on a deliberately sized volume.
Aim to keep at least 15–20% free on active filesystems. Free space is not waste; it is room for updates, temporary files, database maintenance, and recovery.
Check deleted files and mounts
If du does not explain df, look for deleted files still held open:
sudo lsof +L1
Restart the owning service gracefully. If the largest path is a separate mount, inspect that mount rather than deleting files from the underlying root directory. Check findmnt before changing storage layout.
Never delete database files, Docker volumes, mail queues, or user uploads simply because they are large. First identify the owner, confirm a backup, and use the application's retention mechanism. After the incident, add growth alerts, log rotation, backup retention, and a capacity threshold to the runbook.
Continue reading