Monitor Ubuntu VPS Disk Usage with Alerts: Complete Guide

Why Disk Usage Monitoring Matters on a VPS
Running out of disk space on a VPS is one of the most avoidable hosting disasters. When your root partition fills up, MySQL stops writing, mail queues freeze, and your site throws 500 errors — all without any obvious warning unless you've set up alerts in advance.
This guide walks you through how to monitor Ubuntu VPS disk usage on 22.04 or 24.04, set thresholds, and get email notifications before things go wrong. No third-party SaaS required — just standard Linux tools and a cron job.
Step 1: Check Current Disk Usage
Start with the basics. The df command shows disk usage across all mounted filesystems:
df -h
The -h flag outputs human-readable sizes. You'll see something like this:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 40G 28G 10G 74% /
tmpfs 512M 0 512M 0% /dev/shm
Watch the Use% column for your root partition (/) and any data mounts. Once this hits 90%, you're in warning territory. At 95%+, services start failing.
To find what's actually eating space, run du on your heaviest directories:
du -sh /var/* | sort -rh | head -20
This ranks subdirectories of /var by size — which is where log files, mail queues, and databases tend to grow. The usual suspects on hosting servers are /var/log, /var/lib/mysql, and /var/mail.
Step 2: Build a Disk Alert Script
A simple bash script handles the threshold check and fires an alert when usage crosses your limit. Create the file at /usr/local/bin/disk-alert.sh:
#!/bin/bash
THRESHOLD=85
EMAIL="you@yourdomain.com"
HOSTNAME=$(hostname)
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read OUTPUT; do
USAGE=$(echo $OUTPUT | awk '{ print $1}' | cut -d'%' -f1)
PARTITION=$(echo $OUTPUT | awk '{ print $2 }')
if [ $USAGE -ge $THRESHOLD ]; then
echo "WARNING: Disk usage on $HOSTNAME is at ${USAGE}% on partition $PARTITION" | \
mail -s "Disk Alert: ${USAGE}% used on $HOSTNAME" $EMAIL
fi
done
Replace you@yourdomain.com with a real address. The THRESHOLD=85 triggers an alert at 85% — adjust to taste. Many sysadmins run two scripts: one at 80% for early warning, another at 92% for urgent escalation.
Make the script executable:
chmod +x /usr/local/bin/disk-alert.sh
Step 3: Install mailutils for Sending Alerts
The script relies on the mail command. If it's not installed:
sudo apt update && sudo apt install mailutils -y
Ubuntu will prompt you to configure Postfix during installation. For a simple outbound-only setup, choose Internet Site and enter your server's hostname. If you've already configured Postfix, skip this.
Test mail delivery before wiring up the cron job:
echo "Test message from disk monitor" | mail -s "Disk Monitor Test" you@yourdomain.com
If the email doesn't arrive, check /var/log/mail.log for errors. A common issue on fresh VPS instances is that the server hostname doesn't resolve to a valid PTR record — worth fixing early. Our guide on setting up Postfix mail relay on Ubuntu VPS covers this in detail.
Step 4: Schedule the Script with Cron
Once testing passes, automate it. Edit root's crontab:
sudo crontab -e
Add a line to run the check every hour:
0 * * * * /usr/local/bin/disk-alert.sh
Or every 30 minutes on a busy server:
*/30 * * * * /usr/local/bin/disk-alert.sh
Save and exit. Cron picks up the change immediately — no restart needed.
Step 5: Log Alert History Locally
Email alone is unreliable if your mail config has problems. Add local logging so you always have a record. Update /usr/local/bin/disk-alert.sh to append to a log file when a threshold is breached:
LOGFILE="/var/log/disk-alerts.log"
# Inside the if block, add:
echo "$(date '+%Y-%m-%d %H:%M:%S') - WARNING: ${USAGE}% on $PARTITION" >> $LOGFILE
Your full if block should now look like:
if [ $USAGE -ge $THRESHOLD ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - WARNING: ${USAGE}% on $PARTITION" >> $LOGFILE
echo "WARNING: Disk usage on $HOSTNAME is at ${USAGE}% on partition $PARTITION" | \
mail -s "Disk Alert: ${USAGE}% used on $HOSTNAME" $EMAIL
fi
Review the log any time with:
cat /var/log/disk-alerts.log
Step 6: Identify and Clean Up Large Files
When an alert fires, you need to move quickly. Here's a diagnostic sequence to find what's consuming space:
- Find the top 10 largest files system-wide:
find / -type f -printf '%s %p\n' 2>/dev/null | sort -rn | head -10 - Check log rotation is working:
ls -lh /var/log/*.log | sort -k5 -rh | head -10 - Find files older than 30 days in /tmp:
find /tmp -type f -mtime +30 - Check MySQL binary logs (if enabled):
ls -lh /var/lib/mysql/mysql-bin.* 2>/dev/null
Log files are the most common culprit on production servers. If /var/log is ballooning, verify that logrotate is configured correctly. Force a manual rotation with:
sudo logrotate -f /etc/logrotate.conf
For MySQL binary log cleanup, see our guide on MySQL binary logging on Ubuntu VPS — it covers safe retention settings.
Step 7: Add a Second Alert for Critical Threshold
One threshold is useful. Two is better. Copy your script to a second file for the critical-level alert:
sudo cp /usr/local/bin/disk-alert.sh /usr/local/bin/disk-critical.sh
Edit /usr/local/bin/disk-critical.sh and update the threshold and subject line:
THRESHOLD=92
# In the mail command:
mail -s "CRITICAL: Disk ${USAGE}% on $HOSTNAME — action required" $EMAIL
Add a second cron entry for this script:
*/15 * * * * /usr/local/bin/disk-critical.sh
Checking every 15 minutes at the critical threshold gives you a tighter window to respond before services start failing. If you're also tracking CPU and memory, the VPS monitoring guide for 2026 covers which metrics matter most for production hosting.
Step 8: Prevent Future Disk Problems
Alerts tell you when you're in trouble. These habits keep you out of it:
- Configure log rotation properly. Check
/etc/logrotate.d/— most applications drop a config file here, but retention is often set too high. A 14-day rotation is usually enough. - Set MySQL's expire_logs_days. In
/etc/mysql/mysql.conf.d/mysqld.cnf, addexpire_logs_days = 7to stop binary logs from quietly filling the disk. - Run automated backups offsite. Backups that write to the same disk they're backing up consume your space and give you false security. Use an offsite or object-storage destination.
- Review disk usage monthly. A monthly
dusummary in your crontab helps you spot growth trends before they become emergencies.
If the disk keeps filling despite cleanup, it may be time to add storage. On a Hostperl VPS, you can scale storage independently without migrating your entire stack.
Verifying Everything Works
Before relying on this setup in production, test it end-to-end. Temporarily lower the threshold to 1% so the alert fires immediately:
THRESHOLD=1
Run the script manually:
sudo /usr/local/bin/disk-alert.sh
Check your inbox and confirm the log entry was written to /var/log/disk-alerts.log. Once verified, restore the threshold and let cron take over.
Confirm the cron job is active:
sudo crontab -l
Both disk monitoring entries should appear. To verify cron actually ran the script at the expected time, check the system log:
grep CRON /var/log/syslog | tail -20
Pair this with a firewall and intrusion prevention setup — our Fail2Ban custom jails tutorial is a natural complement to a hardened VPS configuration.
Need a VPS with room to grow? Hostperl VPS plans include SSD storage, full root access, and support from people who understand real hosting operations. For high-traffic sites that need more headroom, our dedicated server hosting gives you dedicated resources with no noisy neighbours.
Frequently Asked Questions
How often should I run disk usage checks on a VPS?
Hourly is standard for most hosting environments. If your server processes uploads, handles email, or runs large database operations, every 15–30 minutes is safer. The overhead is negligible.
What should I do if disk usage is stuck above 90%?
Start with du -sh /var/* | sort -rh to find the largest directories. Check log files first, then database files and temporary upload directories. If space is genuinely exhausted by legitimate data, consider adding a mount point or upgrading your storage.
Can I send alerts to Slack or a webhook instead of email?
Yes. Replace the mail command in the script with a curl POST to a Slack incoming webhook or any HTTP endpoint. The threshold logic stays identical — only the delivery method changes.
My script runs but no email arrives. What's wrong?
Check /var/log/mail.log for delivery errors. Common causes include missing PTR records, a misconfigured Postfix myhostname value, or your VPS IP being rejected by the destination server. Run echo "test" | mail -s "test" your@email.com first to confirm the mail stack works before blaming the script.
Does this work on Ubuntu 24.04?
Yes. The script uses standard POSIX-compatible bash and GNU coreutils, which are identical across Ubuntu 20.04, 22.04, and 24.04. No version-specific changes are needed.
