Your VPS was running fine yesterday. Today, uploads fail, MySQL won't start, or every command you type spits back No space left on device. Nothing crashed, nothing got hacked — your disk just quietly filled up while you weren't looking. It happens to almost every server eventually, and the fix is usually faster than the panic suggests.

Symptom: What You'll Actually See

Disk-full problems show up in a handful of predictable ways:

  • SSH login works, but any write operation fails with No space left on device
  • MySQL/MariaDB refuses to start, with errors about not being able to write to disk
  • WordPress or your app throws vague 500 errors with nothing useful in the browser
  • apt, yum, or package installs fail mid-way
  • Cron jobs silently stop running or logs stop updating

The confusing part: sometimes df -h shows plenty of free space, but you're still getting the error. That's a different, sneakier variant — more on that below.

Cause: Where the Space Actually Goes

On a typical Linux VPS, disk space disappears into a few usual suspects:

  • Log files — Apache/Nginx access logs, PHP error logs, and mail logs grow unbounded without rotation
  • MySQL binary logs — replication/binlog files that never get purged
  • Package manager cache — apt and yum caches pile up over months of updates
  • Old kernels — Ubuntu/Debian keep multiple kernel versions installed by default
  • Backup files left on the same disk — a one-off mysqldump or tar backup that nobody deleted
  • Mail queue — a misconfigured cron job or compromised script sending thousands of bounced emails
  • Docker — old images, stopped containers, and dangling volumes on containerized setups

And then there's the tricky one: deleted-but-open files. If a process still has a file handle open on a file you deleted, the space isn't actually freed until that process closes the handle or restarts. This is why df and du can disagree — du counts what's on disk right now, df counts what the filesystem has actually reserved, including space held open by running processes.

Fix: Step-by-Step Cleanup

1. Confirm the problem and find the worst offender

df -h

Look for any filesystem at 90%+ usage. Usually it's / or /var. Then narrow down where the space went:

du -h --max-depth=1 /var | sort -rh | head -10

Repeat this inside whichever directory shows up biggest (often /var/log, /var/lib/mysql, or /var/lib/docker) until you find the actual large files.

2. Clean up logs

du -sh /var/log/* | sort -rh | head -10

# Truncate a huge log without deleting the file (safe for running services)
truncate -s 0 /var/log/apache2/access.log

# Or force logrotate to run now
logrotate -f /etc/logrotate.conf

Truncating instead of deleting matters here — if a service still has the log file open, deleting it won't free the space until the service restarts, but truncating it to zero bytes frees the space immediately.

3. Clear package caches and old kernels

DistroCommand
Debian/Ubuntuapt clean && apt autoremove --purge
CentOS/AlmaLinuxyum clean all or dnf clean all

On Ubuntu, check installed kernels with dpkg --list | grep linux-image and remove any that aren't your current one (keep at least one spare in case the latest fails to boot).

4. Check MySQL binary logs

If you're not using replication, binlogs are pure overhead. Check their size first:

du -sh /var/lib/mysql/*bin*

# In MySQL shell, purge logs older than 3 days
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;

To stop them from piling up again, add expire_logs_days = 7 (or binlog_expire_logs_seconds on MySQL 8+) to your my.cnf.

5. Check the mail queue

mailq | wc -l

A queue with thousands of entries usually means a script or a compromised account is sending spam. Flush it once you've confirmed it's not legitimate mail:

postsuper -d ALL

6. Find the phantom disk usage from deleted-but-open files

If df and du disagree by a large margin, look for processes still holding deleted files open:

lsof +L1

This lists open file handles pointing to files with zero remaining links (i.e., deleted files still consuming space). Restarting the owning service releases the space instantly.

7. Docker cleanup, if applicable

docker system df
docker system prune -a --volumes

Be careful with --volumes on a production box — it removes volumes not attached to a running container, which can include data you meant to keep.

Prevention: Don't End Up Here Again

  • Set up disk usage alerts. If you're on a SkyServer VPS, enable disk monitoring in your control panel so you get warned at 80% instead of finding out at 100%.
  • Confirm logrotate is actually configured for every app you run, not just the OS defaults — custom apps often log straight to a growing file with no rotation policy.
  • Set MySQL binlog expiry so old logs purge automatically instead of accumulating for months.
  • Never store backups on the same disk long-term. Push them to object storage, a separate backup volume, or an off-server destination on a schedule.
  • Take periodic snapshots before large migrations or updates, and clean up old snapshots you no longer need — they consume storage too.
  • Set a cron job to email you the output of df -h weekly if you don't want to rely on a dashboard.

A disk-full VPS looks alarming, but it's rarely a sign anything is actually broken — it's almost always logs, caches, or backups that nobody cleaned up. Find the biggest directory, clear it safely, and put a rotation or alert in place so you're not doing this again in three months.

Frequently Asked Questions

Why does df show my disk is full but du says there's plenty of free space?

This usually means a process is holding a deleted file open. The filesystem still has that space allocated until the process closes the file or restarts. Use lsof +L1 to find the culprit and restart the owning service.

Is it safe to delete files in /var/log?

Deleting the file itself can cause errors if a service still expects it to exist. It's safer to truncate the file to zero bytes with truncate -s 0 filename, or better, let logrotate handle it properly with compression and rotation.

How much free disk space should I keep on a VPS?

Aim to keep usage under 80% at all times. Once you cross 90%, many services (MySQL, in particular) start behaving unpredictably, and you lose the breathing room needed for temp files during updates or backups.

Can a disk-full error corrupt my database?

It's possible, especially if MySQL is mid-write when it runs out of space. This is exactly why keeping free space above a safe threshold matters — recovering from a corrupted table is far more work than clearing 5GB of old logs.

What's the fastest way to check what's using space right now?

Run du -h --max-depth=1 / and sort by size, then drill into the largest directory repeatedly until you find the specific files. It's slower than a GUI tool but works on every server without installing anything extra.