Why Your WordPress Server Ran Out of Disk Space — The Six Places I Always Check

· 11 min read

Last month a client's WooCommerce store went down hard. No white screen, no 500 error — just a completely blank page and a flood of "WordPress database error: disk full" messages in the browser. Orders stopped processing. Their hosting dashboard showed 100% disk usage on a 40GB VPS that should have had plenty of room for a store with 2,000 products.

I've seen this exact scenario dozens of times across the 70+ sites I manage. A WordPress server doesn't run out of disk space because of WordPress content. It runs out because something is silently growing in the background and nobody notices until the server locks up. Here's the diagnostic process I follow every time.

Step 1: Find Where the Space Actually Went

Before touching WordPress, I need to understand what's consuming the disk. SSH in and check the overall situation:

df -h

This shows mounted filesystems and their usage. On most WordPress VPS setups, / or /home is what fills up. Once I know which partition is full, I drill down:

du -h --max-depth=1 / | sort -hr | head -20

This gives a sorted breakdown of the top-level directories by size. On a WordPress server, the usual suspects are /var (logs and MySQL data), /home (web files), and /tmp. I follow the trail into whichever directory is oversized, repeating the du command one level deeper each time until I find the culprit.

For a faster interactive view, ncdu is invaluable if it's installed:

ncdu /

It gives a navigable tree view of disk usage. I install it on every server I manage.

In my experience, the disk space thief falls into one of six categories.

1. Runaway Log Files

This is the number one cause I see. WordPress, PHP, and the web server all write logs, and none of them have size limits by default.

The most common offenders:

find / -name "*.log" -size +100M -exec ls -lh {} \; 2>/dev/null

On this client's server, the output revealed the problem immediately:

-rw-r--r-- 1 www-data www-data 14G /home/client/public_html/wp-content/debug.log
-rw-r--r-- 1 www-data www-data 3.2G /home/client/public_html/error_log
-rw-r--r-- 1 www-data www-data 1.8G /var/log/nginx/error.log

A 14GB debug.log. Someone had enabled WP_DEBUG and WP_DEBUG_LOG months ago to diagnose a plugin issue, fixed the problem, and forgotten to turn debugging off. Every deprecated function notice, every PHP warning from every plugin on every page load had been appended to that file for months.

The immediate fix is straightforward — truncate the log and disable debug mode:

truncate -s 0 /home/client/public_html/wp-content/debug.log

Then edit wp-config.php:

define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);

But the real fix is setting up log rotation so this can never fill a disk again. I create /etc/logrotate.d/wordpress on every server:

/home/*/public_html/wp-content/debug.log
/home/*/public_html/error_log {
    weekly
    rotate 2
    size 50M
    compress
    missingok
    notifempty
    create 0640 www-data www-data
}

This rotates any debug.log or error_log that exceeds 50MB, keeps two compressed copies, and creates a fresh file. The underlying PHP errors still need fixing — a healthy WordPress site shouldn't be generating gigabytes of log output — but at least it won't take the server down while you investigate.

2. Backup Plugins Storing Locally

This is the second most common cause. Plugins like UpdraftPlus, BackupBuddy, and All-in-One WP Migration store backups inside wp-content by default. A full site backup of a WooCommerce store with product images can easily be 2-5GB per backup. If the plugin is set to run daily and retain 30 copies, that's 60-150GB of backups sitting inside the web root.

I check the usual locations:

du -sh /home/*/public_html/wp-content/updraft/ 2>/dev/null
du -sh /home/*/public_html/wp-content/ai1wm-backups/ 2>/dev/null
du -sh /home/*/public_html/wp-content/backups-dup-lite/ 2>/dev/null
du -sh /home/*/public_html/wp-content/backup-* 2>/dev/null

On a recent rescue job, I found 87GB of UpdraftPlus backups in wp-content/updraft/. The client had configured daily backups with a 90-day retention period but never set up remote storage. Every backup stayed on the same server it was backing up — which defeats the purpose entirely, since a disk failure would take out both the site and all its backups.

The fix: configure the backup plugin to send copies to S3, Google Drive, or any off-server location. Then reduce local retention to 1-2 copies. Delete the accumulated backups:

ls /home/client/public_html/wp-content/updraft/ | wc -l

If there are hundreds of files, remove old ones carefully. I always keep the most recent complete backup set before clearing the rest:

cd /home/client/public_html/wp-content/updraft/
ls -lt | head -20

Identify the latest full backup set (database + plugins + themes + uploads + others), move it somewhere safe, then remove the rest.

3. MySQL Binary Logs and InnoDB Files

This one catches people off guard because it's not in the WordPress directory at all. MySQL/MariaDB binary logs live in /var/lib/mysql/ and can grow silently to tens of gigabytes.

du -sh /var/lib/mysql/
ls -lh /var/lib/mysql/binlog.* 2>/dev/null
ls -lh /var/lib/mysql/*-bin.* 2>/dev/null

Binary logging is enabled by default on many server configurations because it's required for replication. But a standalone WordPress server running a single database rarely needs it. I've found servers with 30GB+ of binary logs that nobody was using.

Check if binary logging is enabled:

mysql -e "SHOW VARIABLES LIKE 'log_bin';"

If it's ON and you're not running replication, either disable it or set an expiry:

SET GLOBAL binlog_expire_logs_seconds = 259200;
PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 3 DAY);

To make the expiry permanent, add to your MySQL/MariaDB config (/etc/mysql/mariadb.conf.d/50-server.cnf or equivalent):

[mysqld]
binlog_expire_logs_seconds = 259200

The other MySQL disk hog is ibdata1, the shared InnoDB tablespace. If innodb_file_per_table was not enabled when the databases were created, all InnoDB data gets packed into a single file that only ever grows — it never shrinks, even if you delete tables. I've seen ibdata1 files over 20GB on WordPress servers.

ls -lh /var/lib/mysql/ibdata1

Fixing a bloated ibdata1 requires exporting all databases, stopping MySQL, deleting the file, restarting, and re-importing. It's a maintenance window job, not a quick fix. But checking innodb_file_per_table is on will prevent the problem from recurring:

SHOW VARIABLES LIKE 'innodb_file_per_table';

If it returns OFF, add innodb_file_per_table = 1 to your MySQL config. New tables will then get their own .ibd files that can be reclaimed when dropped.

4. The Uploads Directory

WordPress media uploads in wp-content/uploads/ can grow large on image-heavy sites, but they usually grow predictably. The surprise comes from plugins that dump generated files into uploads — PDF invoices, CSV exports, temporary image manipulations, and WooCommerce product CSV import files that linger forever.

du -sh /home/*/public_html/wp-content/uploads/

Then drill deeper:

du -h --max-depth=2 /home/client/public_html/wp-content/uploads/ | sort -hr | head -20

I once found 8GB of WooCommerce PDF invoices in uploads/woocommerce-pdf-invoices/ on a store that had been running for four years. The invoices were useful but didn't need to live on the web server indefinitely. We moved anything older than 12 months to S3.

Another common find: uploads/wc-logs/ containing years of WooCommerce debug logs. Check it:

du -sh /home/*/public_html/wp-content/uploads/wc-logs/ 2>/dev/null
find /home/*/public_html/wp-content/uploads/wc-logs/ -name "*.log" -mtime +30 -delete 2>/dev/null

That deletes WooCommerce log files older than 30 days.

5. WordPress Post Revisions

This one doesn't fill the server disk as dramatically as the others, but on long-running WooCommerce sites with thousands of products that get regularly updated, the wp_posts table can balloon.

WordPress stores every saved revision of every post and page by default, with no limit. A product page edited 50 times has 50 revisions in the database. Multiply that across thousands of products and you get a wp_posts table that's several gigabytes larger than it needs to be.

Check how many revisions exist:

wp db query "SELECT COUNT(*) as revision_count FROM wp_posts WHERE post_type = 'revision';" --path=/home/client/public_html/

On a client site last year, this returned 340,000 revisions. The wp_posts table was 2.1GB, of which 1.4GB was revisions.

Clean up old revisions with WP-CLI:

wp post delete $(wp post list --post_type=revision --format=ids --path=/home/client/public_html/) --path=/home/client/public_html/

Then prevent the problem from recurring by adding a revision limit to wp-config.php:

define('WP_POST_REVISIONS', 5);

This keeps the five most recent revisions per post — enough to recover from mistakes without accumulating hundreds of thousands of unused rows.

After deleting revisions, optimise the table to reclaim the disk space:

wp db optimize --path=/home/client/public_html/

6. Stuck Temporary Files and Orphaned Cache

The last place I check is the temp and cache directories. PHP stores upload temp files and session data that should be cleaned up automatically but sometimes isn't:

du -sh /tmp/
du -sh /var/tmp/

Caching plugins also store generated files on disk. A misconfigured page cache on a WooCommerce store with query string variations can generate hundreds of thousands of cached files:

du -sh /home/*/public_html/wp-content/cache/ 2>/dev/null
du -sh /home/*/public_html/wp-content/litespeed/ 2>/dev/null

I've seen LiteSpeed Cache directories grow to 5GB+ on sites with thousands of product variations, each generating a separate cached page.

The fix depends on the caching plugin, but generally: purge the cache, review the caching rules (exclude unnecessary query strings from caching), and set up a cron job to alert you when disk usage crosses 80%.

Setting Up a Disk Space Alert

After cleaning up, I always configure a simple monitoring alert so the problem doesn't recur silently. A one-liner in crontab does the job:

crontab -e
0 */6 * * * [ $(df / --output=pcent | tail -1 | tr -d ' %') -gt 80 ] && echo "Disk usage above 80% on $(hostname)" | mail -s "DISK ALERT: $(hostname)" [email protected]

This checks disk usage every six hours and sends an email if it exceeds 80%. On servers where I run Uptime Kuma or a Telegraf stack, I set the threshold there instead and get Slack notifications.

The Recurring Theme

Every one of these problems has the same root cause: something is writing to disk without a size limit or retention policy. WordPress core, plugins, MySQL, and PHP all assume someone else is managing the disk. Nobody is — unless you set it up.

On every server I onboard into my maintenance plans, I configure log rotation, backup retention, binary log expiry, revision limits, and disk monitoring before anything else. It takes 30 minutes and prevents the kind of midnight emergency that brought this client's store down.

If your WordPress site just went down with a "database error disk full" message and you need it back online now, I offer emergency support with same-day response. If you'd rather prevent it from happening in the first place, server management is what you need.

Stop Firefighting. Start Maintaining.

I manage 70+ WordPress sites for UK agencies and businesses. Whether you need ongoing maintenance, emergency support, or a one-off performance fix — I can help.

View Maintenance Plans Get in Touch

Get in Touch to Discuss Your Needs