Skip to main content
Cloud & DevOps (AWS)

100% Disk Usage! How I Saved My WordPress Server from Repeated Crashes on AWS

A real 100% disk usage outage on an AWS WordPress server: the df/du diagnosis, the backup-pileup root cause, and the automation that ended the crashes.

7 min
Read time
1,293
Words
Published
Last revised
Engr Mejba Ahmed

Written by

Engr Mejba Ahmed

Share Article

100% Disk Usage! How I Saved My WordPress Server from Repeated Crashes on AWS

The most dangerous thing about a full disk on a WordPress server is that it never announces itself as a full disk. It announces itself as a database error, a failed upload, a site that's simply gone — and if you chase those symptoms individually, you'll fix nothing and the crash will come back on schedule. That's exactly what happened to me: my WordPress sites on an AWS EC2 instance went down repeatedly over several weeks, uptime alerts firing in the middle of the night, and the root cause every single time was the same line in df -h: the root volume at 100%.

Here's the full incident — diagnosis, the actual root cause (which wasn't what I expected), the cleanup that brought the sites back, and the two pieces of automation that have kept this class of crash from ever recurring.

100% Disk Usage! How I Saved My WordPress Server from Repeated Crashes on AWS - overview of what 100% disk usage actually looks like from the outside, finding the disk hogs

What 100% disk usage actually looks like from the outside

When a Linux server exhausts its disk, everything that writes starts failing at once, and each service fails with its own vocabulary:

  • WordPress throws "error establishing a database connection" — because MySQL can't write, not because MySQL is misconfigured
  • Pages come back blank or half-rendered as PHP fails to write session and cache files
  • Uploads die with permission-looking errors that have nothing to do with permissions
  • Logs fill with "No space left on device" — right up until logging itself stops
  • In the worst case, even SSH gets weird: you can log in but can't save a file

The diagnostic reflex worth burning into your fingers: any of those symptoms on a previously healthy site gets an immediate df -h. If / or /dev/xvda1 shows 100%, stop chasing the symptom — you've found the disease.

There's also an earlier warning window that I missed and now watch for. Disk exhaustion telegraphs itself in order of write size: scheduled backups fail first (biggest writes), then media uploads, then cache writes. If your backup plugin has been silently failing for a week, you are not watching a backup problem — you're watching a fuel gauge.

Finding the disk hogs

With SSH access, two commands localize the problem in under a minute:

df -h
sudo du -h --max-depth=1 / | sort -hr | head -20
sudo du -h --max-depth=1 /var/www | sort -hr | head -20

Walk the tree with du one level at a time, following the biggest directory down. On my server the trail led to /var/www/temp — and to the actual root cause.

Over 14GB of stale backup archives. An automated backup process had been dutifully writing .zip and .tgz files to a temp directory for months, and nothing had ever deleted one. Every few weeks the pileup crossed the line, the disk hit 100%, the sites crashed, and whoever was firefighting (me) deleted a few obvious files, got the sites up, and moved on — leaving the generator running. That's why the crash repeated: the cleanup treated the symptom, and the backup job was the disease.

The secondary offenders were familiar ones: bloated WordPress cache directories on a couple of sites, and error logs that had been quietly appending for a year. On a multi-site server, a few gigabytes here and there compound fast.

The cleanup that brought it back

The commands I actually ran, in order of payoff:

sudo rm -rf /var/www/temp/*          # the 14GB of dead backups
sudo rm -rf /var/log/*.gz /var/log/*.1   # rotated, compressed old logs
sudo journalctl --vacuum-time=3d     # systemd journal, capped to 3 days
sudo rm -rf /tmp/*

Then verify: df -h dropped from 100% to 72% immediately, and the sites came back.

Two hard-won caveats before you paste those into your own terminal:

Deleting an open log file frees nothing. If a process still holds the file handle, the space stays allocated until the process restarts. If df doesn't budge after a big delete, run sudo lsof +L1 to find deleted-but-open files, then restart the offending service. This one cost me twenty confused minutes the first time I hit it.

Restart MySQL deliberately after a full-disk incident. MySQL that hit a wall mid-write can be in a wounded state even after space returns. Restart it and then actually read the error log — InnoDB will tell you whether it recovered cleanly:

sudo systemctl restart mysql
sudo systemctl restart nginx
sudo tail -50 /var/log/mysql/error.log

If InnoDB reports crash recovery, verify your most important tables before declaring victory. A disk-full crash during a write is one of the few mundane events that can genuinely corrupt data.

The automation that made it permanent

Freeing space bought me weeks. Three pieces of automation ended the cycle, and together they took maybe half an hour to set up.

1. CloudWatch disk alarms — the one I'm most embarrassed I didn't have. EC2 doesn't report disk usage out of the box; you need the CloudWatch agent publishing the disk_used_percent metric. I set alarms at 75%, 85%, and 95%, notifying email. The alarm converts the failure mode from "sites down at 3 AM" into "calm ticket on Tuesday," which is the entire difference between ops and firefighting.

2. Snapshot backups with a retention policy, off the local disk. The original sin was backups accumulating on the same volume they were protecting — which is also useless as disaster recovery, since the backup dies with the disk. I moved to AWS Data Lifecycle Manager for weekly EBS snapshots with automatic expiry of old ones, and pointed WordPress-level backups at S3 instead of the local filesystem. If you're offloading media too, WP Offload Media with S3 takes the uploads directory out of the equation entirely.

3. A cleanup cron for anything that still lands locally:

# weekly: purge the temp directory the backup job writes through
0 3 * * 0 rm -rf /var/www/temp/*

Plus standard logrotate for the system side. The rule I took from the whole incident: every automated process that writes to disk needs a paired process that deletes. A backup job without a retention policy isn't a backup strategy — it's a slow-motion outage.

When cleanup isn't enough: grow the volume

Sometimes the disk is full of things you legitimately need, and no amount of pruning fixes an undersized volume. That's a different playbook — resizing the EBS volume and growing the filesystem live — and I wrote it up separately in my guide to fixing a full disk by increasing the EBS volume. The decision rule I use: if you're above 80% after an honest cleanup, or if growth is organic (real media, real database), resize. If you're above 80% because of logs, caches, and backups, resizing just buys the disease a bigger host.

It's worth saying that disk exhaustion is only one of the ways WordPress dies with a misleading error message on the screen — I walked through another full diagnosis in our "critical error on your website" case study, and the method is the same: ignore the symptom's wording, find the layer that's actually failing.

The checklist I'd hand my past self

  • Any weird WordPress error on a healthy site → df -h first, always. It costs three seconds.
  • du -h --max-depth=1, walked downward, finds the hog in a minute.
  • Deleted a big file and df didn't move → lsof +L1, restart the holder.
  • After any full-disk incident, restart MySQL and read the InnoDB log — don't assume.
  • CloudWatch agent + alarms at 75/85/95 on disk_used_percent. Non-negotiable.
  • Backups go off the volume (S3, snapshots), with retention policies. Local backup archives are a countdown timer.
  • Every writer gets a deleter: cron cleanup or logrotate for anything that appends forever.

I've run WordPress on AWS for clients for 8+ years, and this incident class is the single most common "mystery outage" I get called into — and the most preventable. If your server is crashing on a schedule and the errors don't make sense, the disk is where I'd look first, and I'm happy to look at it with you.

Advertisement
Coffee cup

Enjoyed this article?

Your support helps me create more in-depth technical content, open-source tools, and free resources for the developer community.

Related Topics

Engr Mejba Ahmed

Engr Mejba Ahmed

Engr. Mejba Ahmed builds AI-powered applications and secure cloud systems for businesses worldwide. With 8+ years shipping production software in Laravel, Python, and AWS, he's helped companies automate workflows, reduce infrastructure costs, and scale without security headaches. He writes about practical AI integration, cloud architecture, and developer productivity.

Related Articles

Browse All

Comments

Leave a Comment

Comments are moderated before appearing.

Learning Resources

Expand Your Knowledge

Accelerate your growth with structured courses, verified certificates, interactive flashcards, and production-ready AI agent skills.

Sample Certificate of Completion

Sample certificate — complete any course to earn yours

Engr Mejba Ahmed

Engr Mejba Ahmed

AI assistant · trained on my work

👋

Hey there!

Quick Actions

WhatsApp Direct line to me

Chat on WhatsApp

+880 1723 741224 · Replies within the hour on working days

Popular Questions

Engr Mejba Ahmed is connected
Engr Mejba Ahmed is typing...
Engr Mejba Ahmed avatar

✉ Want me to follow up? Drop your email

Engr Mejba Ahmed avatar

📞 Connect Directly

Choose how you'd like to reach me

WhatsApp

+880 1723 741224

Email

mejba.13@gmail.com

✓ Details sent! I'll get back to you shortly.

Powered by OpenAI

335+

Blog Posts

25

AI Courses

63

Projects

Services & Expertise

Pricing & Process

Learning & Resources

Connect & Support