Without server monitoring, the first alert may be a customer reporting that the site is down. A useful monitoring setup checks the service from outside, watches resource pressure inside the VPS, and sends an alert to someone who can act.
The right alert interval depends on the service and the monitoring plan. The goal is to detect sustained CPU, memory, disk, and service failures early without waking someone for every harmless one-minute spike.
Here's how to set up practical monitoring without spending money or drowning in dashboards you'll never check.
Layer 1: External uptime monitoring (free, 5 minutes)
This catches the big one — "is my site reachable from the outside?" No server-side installation needed.
UptimeRobot (free tier)
- Sign up at uptimerobot.com
- Add monitor → HTTP(s) → enter your URL
- Check interval: 5 minutes (free tier)
- Alert contacts: start with email or the notification channel included in your plan
UptimeRobot's available intervals and notification channels depend on its current plan. Configure the fastest interval you genuinely need, and require more than one failed check when brief network blips would create noisy alerts.
Pro tip: Monitor specific pages, not just the homepage:
https://yourdomain.com— main sitehttps://yourdomain.com/wp-admin/— WordPress admin (catches PHP crashes)https://yourdomain.com/health— custom health endpoint if you have one
Alternative: Better Uptime, Hetrix Tools
Both offer free tiers with more features. Hetrix Tools includes server-side monitoring agents on their free plan.
Layer 2: Server resource monitoring (command line)
When you SSH into your VPS, these commands tell you what's happening right now.
Memory status
bashfree -h
Watch the available column. Under 200MB on a 4GB VPS = danger zone.
CPU and process overview
bashhtop
Better than top — install it: sudo apt install htop. Color-coded, sortable, shows CPU per core. Press F6 to sort by memory or CPU. For a deeper walkthrough of htop, journalctl, and alerting on Ubuntu, see Ubuntu Server Monitoring: journalctl, htop & Alerts.
Disk usage
bashdf -h
If / is above 85%, start cleaning. At 100%, MySQL stops writing and your site crashes.
bash# Find the biggest space consumers: sudo du -sh /var/log/* | sort -rh | head -10 sudo du -sh /var/www/* | sort -rh | head -5
Log files are the usual culprit. A busy WordPress site can generate gigabytes of access logs.
What's using the network
bashsudo apt install iftop -y sudo iftop
Shows real-time bandwidth per connection. Useful for spotting unexpected traffic spikes or DDoS attempts.
Layer 3: Automated alerts (the important part)
Command-line tools are useless if you're not logged in. Set up automated alerts that come to you.
Simple bash monitoring script
Create /usr/local/bin/server-monitor.sh:
bash#!/bin/bash ALERT_EMAIL="[email protected]" HOSTNAME=$(hostname) # Check available memory AVAILABLE_MB=$(free -m | awk '/Mem:/{print $7}') if [ "$AVAILABLE_MB" -lt 200 ]; then echo "LOW MEMORY: ${AVAILABLE_MB}MB available on $HOSTNAME" | \ mail -s "⚠️ Memory Alert: $HOSTNAME" "$ALERT_EMAIL" fi # Check disk usage DISK_PERCENT=$(df / | awk 'NR==2{print $5}' | tr -d '%') if [ "$DISK_PERCENT" -gt 85 ]; then echo "DISK WARNING: ${DISK_PERCENT}% used on $HOSTNAME" | \ mail -s "⚠️ Disk Alert: $HOSTNAME" "$ALERT_EMAIL" fi # Check if Nginx is running if ! systemctl is-active --quiet nginx; then echo "Nginx is DOWN on $HOSTNAME" | \ mail -s "🔴 Nginx Down: $HOSTNAME" "$ALERT_EMAIL" sudo systemctl restart nginx # Auto-restart fi # Check if PHP-FPM is running if ! systemctl is-active --quiet php8.3-fpm; then echo "PHP-FPM is DOWN on $HOSTNAME" | \ mail -s "🔴 PHP-FPM Down: $HOSTNAME" "$ALERT_EMAIL" sudo systemctl restart php8.3-fpm # Auto-restart fi # Check if MySQL is running if ! systemctl is-active --quiet mysql; then echo "MySQL is DOWN on $HOSTNAME" | \ mail -s "🔴 MySQL Down: $HOSTNAME" "$ALERT_EMAIL" sudo systemctl restart mysql # Auto-restart fi
bashsudo chmod +x /usr/local/bin/server-monitor.sh # Run every 5 minutes via cron sudo crontab -e # Add: */5 * * * * /usr/local/bin/server-monitor.sh
Install mail utility:
bashsudo apt install mailutils -y # Or use msmtp for SMTP relay to Gmail/external provider
This simple script catches the most critical issues: low memory, full disk, and crashed services — with auto-restart for services.
Systemd auto-restart (belt and suspenders)
Configure critical services to restart automatically on failure:
bashsudo mkdir -p /etc/systemd/system/nginx.service.d/ sudo tee /etc/systemd/system/nginx.service.d/restart.conf << 'EOF' [Service] Restart=on-failure RestartSec=5 EOF sudo mkdir -p /etc/systemd/system/mysql.service.d/ sudo tee /etc/systemd/system/mysql.service.d/restart.conf << 'EOF' [Service] Restart=on-failure RestartSec=5 EOF sudo systemctl daemon-reload
Now if MySQL or Nginx crash, systemd restarts them within 5 seconds — often before users notice.
Layer 4: Log monitoring
Logs tell you about problems that haven't caused downtime yet — 404 errors, failed login attempts, slow queries, PHP warnings.
Watch for errors in real time
bash# PHP errors sudo tail -f /var/log/php8.3-fpm.log # Nginx errors sudo tail -f /var/log/nginx/error.log # WordPress-specific (if WP_DEBUG_LOG is on) sudo tail -f /var/www/html/wp-content/debug.log # Failed SSH login attempts sudo tail -f /var/log/auth.log | grep "Failed"
Log rotation (prevent disk fill)
Make sure logrotate is configured:
bashcat /etc/logrotate.d/nginx
If Nginx logs aren't being rotated, they'll grow indefinitely. A busy site generates 50–100MB of access logs per day. In a month, that's 1.5–3GB.
bash# /etc/logrotate.d/nginx (should already exist, but verify) /var/log/nginx/*.log { daily missingok rotate 14 compress notifempty create 0640 www-data adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript }
What to monitor for WordPress specifically
| Metric | Why | How to check |
|--------|-----|-------------|
| TTFB | Detects PHP/DB slowdowns | curl -w "%{time_starttransfer}" -o /dev/null -s https://yourdomain.com |
| PHP-FPM active workers | Approaching max_children = 502 errors soon | pm.status_path in PHP-FPM config |
| MySQL connections | Too many = connection errors | mysqladmin -u root status |
| OOM killer events | Memory pressure killing services | dmesg \| grep "killed process" |
| SSL expiry | Expired cert = scary browser warning | certbot certificates |
Monitoring stack recommendation by budget
$0/month (minimum viable):
- UptimeRobot (external)
- Custom bash script with cron (internal)
- Systemd auto-restart
$5–10/month (better visibility):
- Add Hetrix Tools agent (server metrics dashboard)
- Or Netdata (self-hosted, beautiful dashboards)
$15+/month (professional):
- Datadog, New Relic, or Grafana Cloud
- Only worth it if you're managing multiple servers or running a business where minutes of downtime cost real money
For a single VPS running WordPress or a web app, the $0 stack catches 95% of problems. Don't over-engineer monitoring — the goal is knowing when something breaks, not building a NASA mission control dashboard.
The hosting advantage
Some hosting providers include monitoring and auto-recovery as part of the service. On a self-managed VPS, you build all of this yourself. On a managed VPS like HostAccent, the infrastructure monitoring layer is handled — so you focus on your application, not on whether MySQL is still running at 3 AM.











Discussion
Have a question or tip about this topic? Share it below — your comment will appear after review.