- Why Does VPS Disk Fill Up Silently?
- Check Disk Usage First
- Find Large Files and Directories
- Clean Log Files Safely
- Clean apt/yum Package Cache
- Clean Temp Files and Old Kernels
- Clean Docker Images and Volumes
- Configure logrotate to Prevent Recurrence
- Monitor Disk Before It Fills Up
- Frequently Asked Questions
- Summary
1. Why Does VPS Disk Fill Up Silently?
A VPS that has been running for a while often hits disk full without warning. Several sources accumulate disk space quietly: web server access logs grow daily, package managers cache downloaded files, database binary logs pile up, or unused Docker images sit dormant consuming gigabytes.
The consequences of a full disk are usually more severe than expected:
| Service | Behavior When Disk Full | Severity |
|---|---|---|
| Nginx / Apache | Returns HTTP 500, cannot write logs | 🔴 High |
| MySQL / MariaDB | Crash, cannot commit transactions | 🔴 High |
| Mail Server | Stops accepting / sending email, queue fills | 🟠 Medium |
| PHP-FPM | Session write fails, PHP errors | 🟠 Medium |
| Cron Jobs | Cannot create temp files to execute | 🟡 Low |
df -h shows Use% above 90%, act immediately. Linux reserves ~5% of disk space for root-only writes, so regular users and services will hit "disk full" errors before the disk actually reaches 100%.
2. Check Disk Usage First
Always start with an overview of disk usage across the entire system:
# Check all filesystems in human-readable format
df -h
# Check only main disk (exclude tmpfs)
df -h --type=ext4 --type=xfs
# Check inode usage (small files can exhaust inodes before disk space)
df -i
Example output to analyze:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 50G 47G 3.0G 94% /
tmpfs 1.9G 1.2M 1.9G 1% /dev/shm
df -i — if IUse% exceeds 90%, you need to delete many small files specifically.
3. Find Large Files and Directories
Once you know the disk is full, the next step is identifying what is consuming the most space:
Method 1: du + sort (No Installation Required)
# Find 20 largest directories from root
du -ah / --max-depth=3 2>/dev/null | sort -rh | head -20
# Check /var specifically (most common culprit)
du -sh /var/* 2>/dev/null | sort -rh | head -10
# Find files larger than 100MB
find / -type f -size +100M -not -path "/proc/*" 2>/dev/null | xargs du -sh | sort -rh
Method 2: ncdu (Recommended — Interactive Interface)
# Install ncdu
apt install ncdu -y # Ubuntu/Debian
yum install ncdu -y # CentOS/RHEL
# Scan and browse interactively
ncdu /
# Or scan only /var
ncdu /var
/var/log — web server, mail, syslog entries/var/cache/apt — downloaded package files/var/lib/mysql — MySQL binary logs/tmp — temporary files/home — user files and uploads/var/lib/docker — Docker images and volumes
4. Clean Log Files Safely
Log files are the most common cause of disk full on a running VPS. Here is how to clean them safely:
Nginx / Apache Logs
# Check log sizes
ls -lh /var/log/nginx/
ls -lh /var/log/apache2/
# Truncate log content (SAFE — keeps file open for process)
> /var/log/nginx/access.log
> /var/log/nginx/error.log
> /var/log/apache2/access.log
> /var/log/apache2/error.log
# Reload service to re-open file descriptor
nginx -s reopen
# or
systemctl reload nginx
System Logs (/var/log)
# Find large log files in /var/log
find /var/log -name "*.log" -size +50M | xargs ls -lh
# Remove journal logs older than 7 days
journalctl --vacuum-time=7d
# Or limit journal size to 200MB
journalctl --vacuum-size=200M
# Delete compressed old logs (already rotated)
find /var/log -name "*.gz" -mtime +30 -delete
find /var/log -name "*.1" -mtime +7 -delete
MySQL/MariaDB Binary Logs
# List binary logs
ls -lh /var/lib/mysql/mysql-bin.*
# Purge binary logs older than 7 days (run in MySQL)
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"
# Disable binary logs if replication is not used (edit /etc/mysql/mysql.conf.d/mysqld.cnf)
# skip-log-bin
rm will not free disk space — the file descriptor remains active until the process closes it. Always use truncate (>) or logrotate for safe log cleanup.
5. Clean apt/yum Package Cache
Package managers accumulate .deb or .rpm files after every installation. These are safe to remove completely:
Ubuntu / Debian (apt)
# Clean all cached packages
apt clean
# Remove unused dependency packages
apt autoremove -y
# Check cache size before cleaning
du -sh /var/cache/apt/archives/
# Aggressive clean including package lists
apt clean && apt autoclean
CentOS / RHEL / Rocky Linux (yum/dnf)
# Clean yum cache
yum clean all
# Clean dnf cache (CentOS 8+/Rocky)
dnf clean all
# Remove unused packages
dnf autoremove
| Command | What It Cleans | Average Space Recovered |
|---|---|---|
apt clean | Cached .deb files | 200MB – 2GB |
apt autoremove | Unused dependency packages | 50MB – 500MB |
journalctl --vacuum-time=7d | Old system journal entries | 100MB – 1GB |
| Nginx log truncate | Access and error log content | 100MB – 10GB+ |
docker system prune | Unused Docker resources | 1GB – 20GB+ |
6. Clean Temp Files and Old Kernels
Temporary Files
# Check /tmp size
du -sh /tmp/
# Delete files in /tmp older than 7 days
find /tmp -type f -mtime +7 -delete
find /tmp -type d -empty -delete
# Clean /var/tmp older than 30 days
find /var/tmp -type f -mtime +30 -delete
Old Linux Kernels
# List installed kernels
dpkg --list | grep linux-image
# Show currently running kernel (do NOT remove this one)
uname -r
# Auto-remove old kernels (Ubuntu handles this automatically)
apt autoremove --purge -y
# Manually remove a specific old kernel
dpkg --purge linux-image-OLD-VERSION-generic
/var/lib/php/sessions/. Clean them with: find /var/lib/php/sessions/ -type f -mtime +1 -delete
7. Clean Docker Images and Volumes
If your VPS runs Docker, it can be one of the biggest disk consumers — especially old images from builds and stopped containers:
# Check Docker disk usage
docker system df
# Remove stopped containers + unused images + networks + build cache
docker system prune -f
# Remove everything including volumes (WARNING: data will be lost)
docker system prune -af --volumes
# Remove only dangling images (untagged)
docker image prune -f
# List and remove unused volumes
docker volume ls -qf dangling=true | xargs -r docker volume rm
docker volume inspect <volume_name> first.
8. Configure logrotate to Prevent Recurrence
A one-time cleanup is not enough. Configure logrotate to automatically rotate logs before they grow too large:
# View existing nginx logrotate config
cat /etc/logrotate.d/nginx
# Create or update nginx logrotate config
cat > /etc/logrotate.d/nginx << 'EOF'
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
nginx -s reopen
endscript
}
EOF
# Test the configuration
logrotate -d /etc/logrotate.d/nginx
# Force run logrotate now
logrotate -f /etc/logrotate.conf
Cron Jobs for Automated Cleanup
# Open crontab
crontab -e
# Clean apt cache every Sunday at midnight
0 0 * * 0 apt clean && apt autoremove -y >> /var/log/apt-cleanup.log 2>&1
# Vacuum journal logs every day at 2 AM
0 2 * * * journalctl --vacuum-time=7d >> /var/log/journal-cleanup.log 2>&1
rotate 14 to keep 14 days of logs, enable compress for gzip compression, and use daily rotation — this typically reduces log storage by 70–90% compared to no rotation at all.
9. Monitor Disk Before It Fills Up
The best approach is knowing about disk issues before they become critical. Set up proactive alerts:
Simple Disk Alert Script via Email
#!/bin/bash
# /usr/local/bin/disk-alert.sh
THRESHOLD=80
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$DISK_USAGE" -gt "$THRESHOLD" ]; then
echo "WARNING: Disk usage is ${DISK_USAGE}% on $(hostname)" | \
mail -s "Disk Alert: ${DISK_USAGE}% used" [email protected]
fi
# Schedule check every 6 hours
0 */6 * * * /usr/local/bin/disk-alert.sh
Using Netdata (Recommended)
# Install Netdata
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# Access dashboard at http://YOUR_IP:19999
# Configure alerts in /etc/netdata/health.d/
| Tool | Pros | Cons |
|---|---|---|
| df + cron script | Lightweight, no extra installation | Alert only, no visualization |
| Netdata | Beautiful real-time dashboard | Consumes ~100MB RAM |
| Prometheus + Grafana | Full historical data and alerting | Complex setup, needs Node Exporter |
| Zabbix | Versatile alerting options | Complex to install and configure |
10. Frequently Asked Questions
du -ah / | sort -rh | head -20 to find the 20 largest files and directories. Alternatively, install ncdu and run ncdu / for an interactive visual interface that is easier to navigate.> /var/log/nginx/access.log but never delete the file while the process holds it open. Use logrotate or truncate instead of rm for safe log management.apt clean is completely safe. It only removes cached .deb files that have already been installed. If you need to reinstall any package, apt will simply re-download it. Running apt autoremove -y is also safe for removing unused packages.docker system prune -af to remove all unused images, containers, and build cache. Add --volumes flag only if you want to remove data volumes too — this is irreversible.Summary
Fixing a VPS disk full issue comes down to three steps: (1) diagnose with df -h and identify the culprits with ncdu or du, (2) clean safely — old logs, apt cache, temp files, unused Docker resources, and (3) prevent recurrence with logrotate, automated cron cleanup, and disk monitoring. If the disk remains critically low after cleanup, it may be time to upgrade your VPS package.
Emergency cleanup commands (run when disk is critically full):
apt clean && apt autoremove -y
journalctl --vacuum-time=3d
> /var/log/nginx/access.log
find /tmp -mtime +1 -delete
df -h # verify result