Operations
Linux VPS Disk Full? A Safe, Step-by-Step Troubleshooting Guide

A Linux VPS can stop accepting uploads, writing database records, or completing updates when storage runs out. The right first step is to identify what is exhausted: disk blocks, inodes, or space held by an open file. This guide gives you a repeatable investigation before you delete anything.
Applies to: common GNU/Linux servers such as Ubuntu, Debian, AlmaLinux, and Rocky Linux. Run inspection commands first. Cleanup commands below remove retained data; choose a retention policy before using them.
1. Find the affected filesystem
df -hT
df -i
findmnt /
findmnt /var
In df -hT, check the filesystem containing the failing application, not just the total capacity of the VPS. A separate /var volume may be full while the root volume has room. In df -i, an inode usage near 100% points toward many small files: sessions, caches, queues, or temporary artifacts. Buying more RAM will not resolve either condition.
2. Locate the directory that is growing
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo du -xhd1 /var/log 2>/dev/null | sort -h
sudo du -xhd1 /var/lib 2>/dev/null | sort -h
These GNU du commands summarize one level of directories. -x keeps the scan on one filesystem; scan a separate mounted volume explicitly. The last lines are the largest directories. Keep narrowing the path instead of running a huge recursive listing. These scans can create noticeable disk I/O, so use a quieter period on a busy server. Error output is hidden here for readability; remove the redirection if results seem incomplete.
For inode exhaustion, compare file counts instead of bytes:
sudo du --inodes -x -d1 /var 2>/dev/null | sort -n
A directory full of application sessions requires an application-aware expiry policy. Do not remove database files from /var/lib or container volumes just because they are large. First identify the owning service and whether the data is recoverable.
3. Explain a mismatch between df and du
sudo lsof +L1
If df reports far more usage than the visible files explain, look for deleted files still held open by a process. Install your distribution’s lsof package if needed. Note the process, file size, and service. Space is released when the last handle closes; a planned service reload or restart may do that, but behavior depends on the application. Do not kill a database process blindly. Files hidden beneath mount points, filesystem metadata, and snapshots can also explain differences.
4. Reduce journal storage deliberately
sudo journalctl --disk-usage
sudo journalctl --rotate --vacuum-size=300M
The second command rotates the active journal and deletes the oldest archived journals to approach the chosen archived-file budget. It removes historical logs. Export incident evidence first and choose a size appropriate to your audit requirements. Total journal usage can still exceed 300 MB because active files count too. See the systemd journalctl reference.
To set an ongoing budget for persistent journals, create /etc/systemd/journald.conf.d/size.conf with:
[Journal]
SystemMaxUse=300M
SystemKeepFree=1G
sudo systemctl restart systemd-journald
sudo journalctl --disk-usage
These example limits apply to persistent storage. Volatile journals use the corresponding RuntimeMaxUse and RuntimeKeepFree settings. Choose values that fit the disk and retention needs; see journald.conf.
5. Verify recovery and prevent a repeat
df -hT
df -i
systemctl --failed
Repeat the operation that failed: upload a small file, save an application record, or rerun the interrupted update. Confirm logs no longer report “No space left on device.” Then fix the source of growth: a looping error, missing log rotation, retained backups, or unbounded cache. As a starting point, alert at 80% and 90% usage for both blocks and inodes, then tune those thresholds to growth rate. Keep backups off the VPS and test restoration before reducing local retention.
For a wider operational review, use our server launch checklist. A larger disk buys time; identifying the growth pattern prevents the next outage.
