“Disk full” is the most common avoidable outage on a budget VPS, and it is almost never caused by your actual content. A 40GB plan holds hundreds of thousands of web pages — what fills it instead is a handful of silent consumers: logs, package caches, Docker layers, and backups stored on the same disk. Here is what eats your space, how to reclaim it in 20 minutes, and how to know when you genuinely need to pay for more.
Why a full disk is dangerous
A full disk does not just make your site slow — writes start failing. The database cannot flush transactions, so you risk corruption; cron jobs fail silently; the mail queue backs up; and some services crash-loop, which fills the disk even faster with their own logs. It is a cascade, it snowballs, and it usually happens at 3 a.m. on the day you are traveling. The good news: on a budget plan, nearly all of it is preventable.
What actually eats your disk
- Systemd journal — by default it can grow to 10% of the disk (4GB on a 40GB plan)
- Web and app logs — Nginx access logs plus PHP-FPM logs typically add 100–500MB per month
- Docker images and build cache — easily 5–15GB if you rebuild frequently
- Database binary logs — MySQL/MariaDB binlogs accumulate 1–2GB before rotation
- Package caches — apt and yum caches sit around 300–800MB
- Old kernels and core dumps — a few hundred MB to 2GB after major upgrades
- Backups written to the same server — the single biggest mistake on budget plans
The 20-minute cleanup
Work top-down: biggest consumers first, cheapest wins first. Each step takes seconds:
- See the damage:
df -hfor space anddf -ifor inodes — a full inode table breaks a server that still shows free space - Find the culprits:
du -h --max-depth=1 / 2>/dev/null | sort -h, or installncdufor an interactive view - Cap the journal:
journalctl --vacuum-size=200M, then setSystemMaxUse=200Min/etc/systemd/journald.confand restart journald - Rotate logs: confirm
logrotateruns daily and keep 7 rotated Nginx/PHP-FPM files instead of 52 - Clear caches:
apt clean(ordnf clean all), thendocker system prune -ato drop unused images and build cache - Remove old kernels:
apt autoremove --purgeafter a successful reboot - Trim binlogs: set
expire_logs_days=3in your MySQL config (orbinlog_expire_logs_seconds) and restart - Move backups off the box: rsync or Borg to a cheap object-storage bucket or a second small VPS
The inode table deserves its own warning. Millions of tiny files — PHP session files, cache entries, mail spools — can exhaust the inode limit while df -h shows space to spare. Check df -i weekly, and keep an eye on any directory that accumulates small files. Deleting half a million cache entries is faster than explaining to a client why their site stopped accepting logins.
Emergency: the disk is already full
If you are reading this while a site is down, stop the bleeding before the full cleanup:
- Free the journal first:
journalctl --vacuum-size=100M— instant, safe, and usually enough to get services writing again - Run
docker system pruneto drop unused images in one command - Truncate the largest rotated logs with
truncate -s 0 /var/log/nginx/*.log.1rather than deleting them (running services keep deleted-file handles alive) - Delete the oldest backup copies that were written to the same disk — then move future backups offsite
- Only then run the full 20-minute cleanup above so it stays fixed
Keep it that way
Cleanup is a habit, not an event. A few one-time settings do the work for you — and if you are shopping for a plan with more headroom, the storage allowances in our budget VPS comparison table are a useful starting point:
- A weekly cron job that alerts you (mail or a webhook) when
dfpasses 70% - Logrotate with daily rotation and compression
- A capped journald, re-checked after every OS upgrade
- Offsite backups from day one — a full server backup on the same disk doubles your usage overnight
- A quarterly
docker system pruneif you build images regularly
| Workload | Typical disk usage on a 40GB plan |
|---|---|
| Single WordPress site | 5–15GB with logs and cache |
| 2–3 sites + mail | 10–20GB |
| Docker host with several apps | 10–25GB |
| Small production database | 5–20GB depending on growth |
When you actually need more disk
Upgrade only when the growth is real and structural: a database that grows every month, a user upload directory that keeps expanding, mail storage, or logs you must retain for compliance. Those deserve a paid storage bump. Everything else — caches, logs, old images — is reclaimable space, and reclaiming it beats paying $5–$10/month more forever. If you do need room to grow, Contabo is known for large storage allocations at budget prices, and InterServer lets you add disk to its flat-rate plans; both are in our budget VPS comparison table.
The bottom line
Before you pay for a bigger plan, spend 20 minutes reclaiming the space you already own. Cap the journal, rotate the logs, prune the images, and move backups offsite. For the vast majority of budget servers, that turns “disk full” from a monthly emergency into a non-event — and keeps your $5 plan exactly where it is.

