
Disk-full incidents don’t fail gracefully. WordPress stops uploading media. MySQL refuses writes. Postfix queues mail forever. In worst cases, even SSH logins fail because the system can’t write temporary files. This disk space troubleshooting tutorial gives you a repeatable workflow to find what filled your VPS, reclaim space safely, and add guardrails so you don’t relive the outage next week.
The commands below assume Ubuntu Server 24.04 LTS. The same workflow applies on Debian 12/13 and AlmaLinux/Rocky, with small path differences. Run everything as root (or with sudo).
Before you delete anything: confirm what “full” actually means
Three different problems can show up as “No space left on device.” The fixes are different:
- Filesystem full (for example,
/or/varis at 100%). - Inodes exhausted (too many small files, even if you still have free GB).
- Disk size vs partition layout (the VM has space, but your partition doesn’t use it).
# 1) Disk usage by filesystem
df -hT
# 2) Inode usage
df -ih
# 3) Identify the block device + partition map
lsblk -o NAME,SIZE,FSTYPE,TYPE,MOUNTPOINTS
What you’re looking for: a mount point at 95–100% (often / or /var). Also watch for IUse% at 100% in df -ih.
On hosting VPSs, /var is a common failure point. Logs, caches, mail, and databases often live there.
If you’re building a new server and want fewer surprises, a HostMyCode VPS gives you room to size storage properly and expand before it becomes an incident.
Disk space troubleshooting tutorial: locate the real top offenders fast
After you know which filesystem is full, move fast and stay focused. Find the biggest consumers without crossing into other mounts. Avoid deleting anything you’ll regret later.
Step 1: find the biggest directories
# Replace /var with the mount point that is full
cd /var
# Directory sizes, one level deep
du -xhd1 2>/dev/null | sort -h
-x stops du from crossing into other mounted filesystems. This matters if you have separate mounts for /home or /var/lib/mysql.
Step 2: find the biggest files (not just directories)
# Largest 25 files within the filesystem
find /var -xdev -type f -printf '%s\t%p\n' 2>/dev/null | sort -n | tail -25 | awk '{printf "%.2f MB\t%s\n", $1/1024/1024, $2}'
On hosting servers, the largest single files are often runaway *.log files. Other common culprits include mail spools, backup archives, and application-generated cache blobs.
Step 3: if you suspect deleted-but-still-open files
A common trap: you delete a huge log file, but the service still holds the file handle open. The filename disappears, but the disk space does not return.
apt update && apt -y install lsof
lsof +L1 | head -200
If you find a large deleted file, restart the service holding it. For example, run systemctl restart nginx or systemctl restart php8.3-fpm. That restart is what actually releases the space.
Quick wins that are usually safe (and actually free space)
These are low-risk on most web hosting VPSs. Still, confirm what you’re removing before you remove it.
Clean APT caches and old packages (Ubuntu/Debian)
apt -y autoremove --purge
apt -y clean
# Optional: show cached package usage
du -sh /var/cache/apt/archives 2>/dev/null || true
Trim journald logs (systemd)
Journald can grow quickly on noisy servers. Crash loops can make it worse.
journalctl --disk-usage
# Keep only 7 days (adjust to your compliance needs)
journalctl --vacuum-time=7d
# Or cap total size
journalctl --vacuum-size=500M
Rotate or compress large plain-text logs
If /var/log is the problem, compressing oversized logs can buy time. Then fix the root cause.
# Identify large logs
du -sh /var/log/* 2>/dev/null | sort -h | tail -20
# Example: compress a large Nginx access log immediately
gzip -9 /var/log/nginx/access.log.1 2>/dev/null || true
If logs keep exploding, treat it as configuration debt. Fix it properly so growth stays bounded.
Pair this guide with centralized log and logrotate setup so you keep enough history to troubleshoot without filling the disk.
Clear temporary files safely
# Preview size first
du -sh /tmp /var/tmp 2>/dev/null || true
# Clean old temp files (24h+)
find /tmp -xdev -type f -mtime +1 -delete
find /var/tmp -xdev -type f -mtime +3 -delete
Don’t wipe /tmp wholesale on a live server. Some running processes expect their temp files to remain in place.
Hosting-specific culprits (WordPress, mail, backups, control panels)
If generic cleanup barely moves the needle, the space is usually tied to your workload. The patterns below show up constantly on hosting VPSs.
WordPress: uploads, cache directories, and backups inside wp-content
WordPress sites often accumulate old backups, cache artifacts, and oversized uploads. It can happen quietly.
# Example paths (adjust for your vhost layout)
cd /var/www/example.com
# Find big directories in wp-content
du -h --max-depth=2 wp-content 2>/dev/null | sort -h | tail -30
# Find huge files (e.g., backup zips)
find wp-content -type f -size +200M -print
- Cache plugins commonly stash gigabytes under
wp-content/cacheorwp-content/w3tc. - Backup plugins often drop archives into
wp-content/updraft,wp-content/ai1wm-backups, or a custom folder. - Staging/copy sites can quietly double media usage.
If you want a safer way to test plugins and changes, see this staging site tutorial. Keep staging storage somewhere you can monitor.
Mail servers: queued mail and oversized mailboxes
On VPS mail setups, /var/spool/postfix and /var/mail can balloon fast. A queue spike often means deliverability trouble. It can also mean an app keeps retrying after SMTP errors.
# Postfix queue size
postqueue -p | head -80
# Spool size
du -sh /var/spool/postfix 2>/dev/null || true
If the queue is jammed, diagnose first. Purge only if you have to.
This guide walks through it: fix a stuck Postfix mail queue. Deleting queued mail can drop legitimate messages, so treat it as a last resort.
Backups stored on the same disk as your website
Local backups can help in a pinch. They are also a predictable way to fill the filesystem you’re trying to protect.
# Look for common backup patterns
find / -xdev -type f \( -name '*.tar' -o -name '*.tar.gz' -o -name '*.zip' -o -name '*.sql' -o -name '*.bak' \) -size +200M 2>/dev/null | head -200
For a safer setup, keep backups offsite and routinely test restores. Use this VPS backup setup guide as your baseline.
cPanel/WHM servers: backups, mail, and bandwidth logs
On cPanel servers, disk often vanishes into:
/backupor a configured local backup mount/home(account files, email, public_html, soft deletes)/usr/local/apache/logsand related stats
If you run WHM, verify you have a remote backup destination and sane retention.
HostMyCode customers often pair WHM servers with managed VPS hosting when they want backups, patching, and monitoring handled consistently across many accounts.
If inodes are full: how to find “too many small files”
Inode exhaustion is common with cache directories, email (lots of small messages), and session files.
# Identify inode-heavy directories (counts files/dirs)
for d in /var/* /home/*; do
[ -d "$d" ] || continue
c=$(find "$d" -xdev 2>/dev/null | wc -l)
printf "%10s %s\n" "$c" "$d"
done | sort -n | tail -20
After you find the inode sink, drill into the specific directory. Clean only what’s safe to delete.
# Example: find number of files in a cache directory
find /var/lib/php/sessions -xdev -type f | wc -l
# Remove stale session files older than 7 days
find /var/lib/php/sessions -xdev -type f -mtime +7 -delete
Tip: If you run PHP-FPM, the session path varies. Check /etc/php/8.3/fpm/php.ini for session.save_path.
Emergency expansion: add space without rebuilding the server
Sometimes cleanup buys minutes, not stability. If traffic, logs, or data growth outpaced your sizing, adding storage is the correct fix.
Option A: grow the filesystem (common on VPS)
The exact steps depend on your layout. Many VPS images use:
- GPT partition table
- one root partition (ext4 or xfs)
- sometimes LVM
For ext4 on a single partition (no LVM):
# Install tools
apt -y install cloud-guest-utils
# Example: grow partition 1 on /dev/vda (verify with lsblk first)
growpart /dev/vda 1
# Resize ext4 filesystem
resize2fs /dev/vda1
df -hT /
For XFS: use xfs_growfs on the mounted filesystem, after you grow the partition/LV.
Option B: attach and mount a new volume for “hot” directories
If resizing root is risky or not available, attach a new disk. Mount it where churn is highest, like /var/www, /home, or /backup.
# Example: new disk is /dev/vdb
lsblk
# Create filesystem
mkfs.ext4 -m 1 -L data1 /dev/vdb
# Mount it (example mountpoint)
mkdir -p /srv/data
mount /dev/vdb /srv/data
# Persist in /etc/fstab
blkid /dev/vdb
# Then add a line like:
# UUID=xxxx-xxxx /srv/data ext4 defaults,noatime 0 2
# Verify
df -hT /srv/data
Then migrate a directory onto it (example: move website files):
systemctl stop nginx php8.3-fpm || true
rsync -aHAX --info=progress2 /var/www/ /srv/data/www/
mv /var/www /var/www.bak
mkdir -p /var/www
mount --bind /srv/data/www /var/www
# Persist bind mount by adding to /etc/fstab:
# /srv/data/www /var/www none bind 0 0
systemctl start php8.3-fpm nginx
Move carefully. A bad entry in /etc/fstab can prevent the server from booting.
If you don’t want to do live storage work solo, use managed VPS hosting so changes get reviewed and executed with a runbook.
Prevent a repeat: caps, rotation, and alerts that actually work
Once the server breathes again, make “disk full” boring. Without limits, these incidents tend to come back.
Set practical logrotate rules for your web stack
First, check what you already rotate:
ls -l /etc/logrotate.d/
logrotate -d /etc/logrotate.conf | head -120
Example: cap a custom application log at 14 days. Compress it so it can’t grow unchecked.
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
}
Pitfall: copytruncate is convenient, but it can lose lines under heavy writes. When you can, reload the service instead.
Limit journald growth permanently
Edit /etc/systemd/journald.conf (create it if needed). Set caps that match your disk size and retention requirements:
# /etc/systemd/journald.conf
SystemMaxUse=500M
RuntimeMaxUse=200M
MaxRetentionSec=7day
systemctl restart systemd-journald
journalctl --disk-usage
Schedule housekeeping + health checks
Disk alerts should fire before the system hits 100%. Simple threshold checks catch most failures early.
If you want a structured routine, follow this Linux server maintenance tutorial and fold disk checks into the same daily report.
Example disk usage check script:
# /usr/local/bin/check-disk-threshold
#!/bin/sh
THRESHOLD=85
df -P -h | awk 'NR>1 {print $5 " " $6}' | while read use mount; do
pct=$(echo "$use" | tr -d '%')
if [ "$pct" -ge "$THRESHOLD" ]; then
echo "Disk warning: $mount is at ${pct}%"
fi
done
chmod +x /usr/local/bin/check-disk-threshold
/usr/local/bin/check-disk-threshold
Monitor disk in a way your team will notice
Monitoring doesn’t need to be fancy. It needs to notify the right people early enough to act.
Use this VPS monitoring tutorial and set disk thresholds at 75% (warning) and 85–90% (critical). Adjust based on how quickly usage can grow.
Final verification checklist (after cleanup or expansion)
- Run
df -hTand confirm your critical filesystem is below 80–85%. - Run
df -ihand confirm inode usage is under control. - Restart services that were failing due to disk full (web, PHP, mail).
- Confirm your site can write uploads, sessions, and cache files.
- Confirm backups are offsite and retention won’t refill the disk.
- Add monitoring alerts before the next incident.
If you keep running out of space, the server is usually undersized or doing too many jobs in one place. Moving to a larger HostMyCode VPS (or splitting web and mail) is often cheaper than repeated downtime.
If you’d rather fix this once and keep it fixed, HostMyCode can help you size storage correctly and put hard limits around logs, caches, and backups. Start with a HostMyCode VPS, or choose managed VPS hosting if you want an expert to handle maintenance, monitoring, and incident response runbooks.
FAQ
Should I delete log files to free space?
Prefer rotation and compression over deletion. If a service is still writing to a log, deleting the file may not reclaim space until the process is restarted. Verify with lsof +L1.
My disk shows free space, but I still get “No space left on device.” Why?
Usually it’s inode exhaustion (df -ih) or a process holding deleted files open (lsof +L1). Less often, a different filesystem (like /var) is the one that’s actually full.
Is it safe to clear /tmp on a production VPS?
Don’t wipe it blindly. Delete old files by age (for example, -mtime +1) so you don’t break running processes.
What’s a good disk usage alert threshold for hosting servers?
Set warning around 75% and critical around 85–90%. If usage can jump suddenly (backups, mail queues), alert earlier.
Should I keep backups on the same disk as my website?
No. Keep short-term local copies only if you have headroom, and push real backups to offsite storage with tested restore steps.