
Disk problems don’t announce themselves politely. One minute the site loads. The next, WordPress can’t update, mail starts bouncing, and SSH returns “No space left on device”. This VPS disk space troubleshooting tutorial gives you a quick, low-risk workflow for Ubuntu/Debian and AlmaLinux/Rocky. It also covers fixes that keep /var from filling again.
If you want to run these steps on a clean VM (with headroom for snapshots and restores), start with a HostMyCode VPS. If this is production and you don’t want to chase disk alerts at 2 a.m., managed VPS hosting is a better fit.
What “disk full” breaks first (and how to confirm it’s storage)
When the root filesystem fills up, failures are usually fast and messy. Common symptoms include:
- Web server errors: 500s, “premature end of script headers”, PHP session write failures
- Database errors: “can’t create/write to file”, temporary table failures
- SSH oddities: can’t create
/tmpfiles, can’t write to~/.ssh/authorized_keys, login loops - Email: queue growth, deferrals, local delivery errors
- Package manager fails:
apt/dnfcan’t unpack
Confirm both space and inode usage first. You can have “free space” and still be stuck because you ran out of inodes. This is common with caches that create millions of tiny files.
df -hT
df -i
Specifically, look for:
- Use% at 95–100% on
/,/var, or a separate mount like/home - Inodes at 100% on the same mount
VPS disk space troubleshooting tutorial: the 15-minute triage workflow
Your first objective is simple: free 1–3 GB so core services can write again. After that, you can clean up properly without racing the clock.
Step 1: Identify the full filesystem and top directories
Get a quick map of where space is going. This is safe to run, and it’s usually fast.
# Root view (may take a minute on large disks)
sudo du -xhd1 / 2>/dev/null | sort -h
# If /var is the hot spot
sudo du -xhd1 /var 2>/dev/null | sort -h
-x keeps the scan on the same filesystem. That matters when you have separate mounts or network storage.
Step 2: Find the biggest files fast (logs, backups, dumps)
# Largest files on the affected filesystem (example: root FS)
sudo find / -xdev -type f -size +200M -printf '%s %p\n' 2>/dev/null | sort -nr | head -50 | awk '{print $1/1024/1024 " MB\t" $2}'
The usual suspects that land in that top 50:
- Runaway logs in
/var/log(web, mail, auth, application) - Backups stored locally in
/homeor/root - Old site archives in
/var/www - Core dumps in
/var/lib/systemd/coredump - Container layers (if Docker/Podman is installed) in
/var/lib
Step 3: If df says full but you can’t find the files, check deleted-but-open files
This is the “ghost space” scenario. A process can keep writing to a file you already deleted. The disk won’t free up until that process closes the file handle.
sudo lsof +L1 | head -200
If you spot a huge entry marked (deleted), restart only the service that owns it. Don’t restart the whole server unless you have to.
# Examples
sudo systemctl restart nginx
sudo systemctl restart apache2
sudo systemctl restart httpd
sudo systemctl restart php8.3-fpm
sudo systemctl restart postfix
When this is the cause, the space often comes back immediately.
Step 4: Check inode exhaustion (millions of tiny files)
If df -i shows 100%, large-file hunting won’t help. You need to find where tiny files are piling up.
# Find directories with huge file counts
sudo bash -lc 'for d in /var/* /var/www/* /home/*; do [ -d "$d" ] && echo -n "$d: " && find "$d" -xdev -type f 2>/dev/null | wc -l; done' | sort -k2 -n | tail -20
Common inode burners on hosting VPS setups:
- WordPress cache directories (plugin caches, page cache, image optimization temp files)
- Session files in
/var/lib/php/sessionsor/var/lib/php/session - Maildirs if you host mailboxes locally (
/home/*/mailon cPanel;/var/mailin some setups)
Safe quick wins: reclaim space without breaking your sites
Once you know what’s consuming the disk, start with low-risk cleanup. Aim for predictable recovery, not an accidental self-inflicted outage.
Clear package caches (Ubuntu/Debian and AlmaLinux/Rocky)
# Ubuntu/Debian
sudo apt-get clean
sudo apt-get autoremove --purge -y
# AlmaLinux/Rocky (DNF)
sudo dnf clean all
sudo dnf autoremove -y
On older servers, this can recover anywhere from a few hundred MB to several GB.
Trim journald logs (systemd) to a fixed size
On busy boxes, the systemd journal can grow quietly. Over time, it can become the problem.
# See current usage
sudo journalctl --disk-usage
# Keep only 7 days OR cap size (pick one)
sudo journalctl --vacuum-time=7d
# or
sudo journalctl --vacuum-size=500M
Clean temporary files safely
Avoid “delete everything in /tmp” unless you know nothing depends on it. Age-based cleanup is safer.
# Delete temp files older than 3 days
sudo find /tmp -xdev -type f -mtime +3 -delete 2>/dev/null
sudo find /var/tmp -xdev -type f -mtime +3 -delete 2>/dev/null
Rotate and compress logs (and fix the one that’s exploding)
If /var/log is the hot spot, identify which log is growing. Don’t rotate everything blindly.
sudo du -h /var/log | sort -h | tail -30
Rotate the problem log, then reload the owning service.
On Debian/Ubuntu, logrotate configs are typically in /etc/logrotate.d/. On AlmaLinux/Rocky, the same path is common.
# Force a logrotate run (useful after adjusting configs)
sudo logrotate -f /etc/logrotate.conf
If you need a hosting-friendly rotation setup that avoids disk spikes (especially with large Nginx/Apache logs), follow this logrotate tutorial for Nginx, Apache, and PHP logs.
Fix the common root causes on hosting VPS (Nginx/Apache, PHP, WordPress, cPanel)
Runaway web access logs (bots, scans, or debug logging)
A burst of probes against /wp-login.php or random paths can inflate access logs quickly. The same problem shows up when debug logging stays enabled after an incident.
Quick diagnostic:
# Top talkers in Nginx access log
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
# Biggest requested paths
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
Two fixes that usually pay off immediately:
- Turn off overly verbose debug logging in your app/web server unless you’re actively debugging.
- Add rate limiting for abusive endpoints. If it’s WordPress login noise, use Nginx rate limiting for WordPress login.
PHP sessions and cache directories filling with tiny files
Session paths vary by distro and PHP version. Locate the active session directory first.
php -i | grep -i '^session.save_path'
Then check both size and file count:
sudo du -sh /var/lib/php/sessions 2>/dev/null || true
sudo find /var/lib/php/sessions -type f 2>/dev/null | wc -l
In most cases, delete only older session files. Many distros handle this with tmpfiles.d timers. Those timers can get misconfigured.
# Delete sessions older than 7 days
sudo find /var/lib/php/sessions -type f -mtime +7 -delete 2>/dev/null
For WordPress, also check wp-content/cache, plugin-specific caches, and image-optimizer temp folders. On cPanel servers, this buildup often lives inside each account’s home directory.
cPanel/WHM backups stored locally (and silently consuming the disk)
Local backups are useful for quick restores. They should not be your only copy.
They also don’t belong on the same small root disk as your live sites.
Check typical cPanel backup paths:
/backup/home/backup/var/cpanel/backups
sudo du -sh /backup /home/backup /var/cpanel/backups 2>/dev/null
If backups are the culprit, fix the backup plan instead of deleting whatever looks big. A practical pattern on a VPS is:
- Local snapshot for fast rollback
- Encrypted offsite backups for real recovery
See snapshot backups with LVM/Btrfs and offsite sync and incremental rsync backups with rotation.
AutoSSL / Let’s Encrypt temp files and renewal failures after a disk-full event
A disk-full incident often turns into an SSL incident later. Renewals fail when the ACME client can’t write challenge files. You might not notice until the certificate is close to expiring.
After you’ve freed space, run a renewal test:
# If you use certbot
sudo certbot renew --dry-run
If you use AutoSSL in WHM, review AutoSSL logs and recent renewal failures. This guide walks through the common failure points: SSL renewal troubleshooting on VPS and cPanel.
Prevent repeat outages: hard limits, monitoring, and safer storage layout
Set log retention limits you can explain to your future self
For most hosting stacks, 7–14 days of compressed web logs is a solid baseline. If you need longer retention, ship logs off-server and keep the VPS lean.
Checklist:
- Confirm logrotate runs daily:
/etc/cron.daily/logrotateor systemd timer - Cap journald usage with
SystemMaxUse=in/etc/systemd/journald.conf - Stop debug logging after the incident
Create a “disk pressure” alert before users see errors
Alerts should trigger at 80–85%. Don’t wait for 100% when everything is already broken.
Minimal approach: a cron job that emails you when a filesystem crosses a threshold.
# /usr/local/sbin/disk-alert.sh
#!/bin/bash
THRESH=85
ALERT_EMAIL="admin@example.com"
df -P -h | awk 'NR>1 {print $5" "$6}' | while read -r use mount; do
pct=${use%%%}
if [ "$pct" -ge "$THRESH" ]; then
echo "Disk usage is ${pct}% on ${mount}" | mail -s "Disk alert: ${mount} at ${pct}%" "$ALERT_EMAIL"
fi
done
sudo chmod +x /usr/local/sbin/disk-alert.sh
sudo crontab -e
# Run every 15 minutes
*/15 * * * * /usr/local/sbin/disk-alert.sh
If you prefer external checks plus on-server health endpoints, use this uptime monitoring tutorial. Add disk thresholds to the same runbook.
Separate high-churn storage (optional, but effective)
On busy VPS and dedicated servers, putting /var (logs, spool, cache) on its own volume contains failures. If /var fills, the base OS can still function.
This is a planned change, not something to attempt mid-outage. If you’re routinely close to the limit, resize storage or move to a larger plan.
For heavy-write workloads, dedicated hardware can be simpler to operate. HostMyCode offers dedicated servers when you want predictable I/O and more room for backups and growth.
Post-cleanup validation: make sure the server is healthy again
Once you’ve recovered space, take two minutes to confirm the system isn’t left in a half-working state.
- Space and inodes:
df -hTanddf -ishow safe headroom - Web server:
nginx -torapachectl configtest, then reload - PHP-FPM:
systemctl status php8.3-fpm(or your version) - SSL renewal dry run:
certbot renew --dry-run(if applicable) - Disk errors in logs:
journalctl -p err..alert -S -2h
If disk pressure started right after a migration, confirm traffic is hitting the new host. Mis-pointed DNS and SSL changes under load can hide what’s really happening. Use this DNS propagation troubleshooting guide to confirm the basics.
Common mistakes to avoid during disk-full incidents
- Deleting random files in /var/lib without understanding what owns them. Stop and identify the service first.
- Truncating logs incorrectly (breaking file permissions). Prefer logrotate or use safe truncation:
: > /path/to/log. - Rebooting as the first step. It can make recovery harder if the system can’t write state files.
- Keeping the only backups on the same disk. A full disk often means backups fail too.
Summary: a repeatable runbook you can keep
Disk space incidents are boring in the best way. The causes repeat.
Confirm the problem with df -hT and df -i. Isolate usage with du and find. If usage doesn’t drop after deletions, check lsof +L1 for deleted-but-open files. Then fix the source (logs, backups, caches, or bot traffic) so you’re not doing the same cleanup next week.
If you want a hosting platform where you can scale storage cleanly and keep snapshots/offsite backups without living on the edge, run these workloads on a HostMyCode VPS. If you’d rather hand off routine maintenance and hardening, managed VPS hosting keeps things stable while you focus on the business.
If disk pressure is a regular event, the server is usually undersized or the storage layout doesn’t match what you’re running. HostMyCode can provision a right-sized VPS quickly, or you can switch to managed VPS hosting for ongoing monitoring, patching, and operational support.
FAQ
How much free disk space should a VPS keep in 2026?
For typical hosting stacks, keep at least 10–15% free on the root filesystem. On small disks, set a hard minimum like 3–5 GB free so updates and log rotation can work.
Why does df show the disk is full even after I delete files?
A process may still have a deleted file open. Run lsof +L1 to find it, then restart only the service holding the handle.
What’s the fastest safe way to free space?
Package cache cleanup (apt-get clean / dnf clean all) plus trimming journald (journalctl --vacuum-size=500M) is usually low risk. After that, fix the specific large log or backup file you identified.
What if the server is out of inodes, not disk space?
Remove directories containing millions of tiny files (sessions, caches, temp files). Use df -i to confirm, then delete old files by age rather than deleting the entire directory at once.
Should I resize the VPS disk or move to a bigger plan?
If growth is steady (backups, uploads, mailboxes, logs), resizing storage is the cleanest fix. If you’re also hitting CPU/RAM limits or I/O saturation, moving up a tier (or to dedicated hardware) tends to reduce incidents and recovery time.