Skip to main content

Site monitoring: UptimeRobot, Zabbix, and system alerts

VDS / VPS · 20.02.2026 · 4 min read
Illustration for “Site monitoring: UptimeRobot, Zabbix, and system alerts”

Every minute of downtime costs money and reputation. Proper monitoring lets you react to problems within minutes, not hours.

UptimeRobot — free monitoring

  1. Sign up at uptimerobot.com
  2. Add New Monitor → HTTP(s)
  3. URL: https://yourdomain.com
  4. Interval: 5 minutes (free plan)
  5. Notifications: Email, Telegram, Slack
✅ UptimeRobot free plan: up to 50 monitors, a 5-minute interval, SMS/email alerts. Enough for most projects.

Telegram alerts from a VPS via bash

#!/bin/bash
# /usr/local/bin/check-site.sh
BOT_TOKEN="YOUR_TOKEN"
CHAT_ID="YOUR_CHAT_ID"
URL="https://yourdomain.com"

HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$URL")

if [ "$HTTP_CODE" != "200" ]; then
  curl -s "https://api.telegram.org/bot$BOT_TOKEN/sendMessage"     -d "chat_id=$CHAT_ID"     -d "text=🚨 Site is down! Code: $HTTP_CODE - $(date)"
fi
chmod +x /usr/local/bin/check-site.sh
# Cron every 5 minutes:
*/5 * * * * /usr/local/bin/check-site.sh

Monitoring server resources

# Install netdata (a nice dashboard)
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# Available at http://YOUR_IP:19999

Useful diagnostic commands

htop              # CPU, RAM, processes
iotop             # Disk load
nethogs           # Traffic by process
df -h             # Disk space
free -h           # RAM usage
ss -tlnp          # Open ports

Diagnosing common problems with the check script

The script reports "site down" even though the site opens fine in a browser — a common cause is that curl without extra flags does not follow redirects and does not set a User-Agent header, so some sites or a WAF return 403 or 301 instead of 200.

$ curl -s -o /dev/null -w "%{http_code}" https://yourdomain.com
403

Add -L to follow redirects and a User-Agent header that mimics a browser if the site is protected against bots: curl -s -L -A "Mozilla/5.0" -o /dev/null -w "%{http_code}" https://yourdomain.com. Test the final command manually from the console before putting it in cron — that way you see the real response code, not just the script's interpretation of it.

A Telegram notification never arrives even though the curl call to the Telegram API succeeds — check Telegram's own response code, not just curl's exit code: a wrong chat_id or a bot that never received /start returns JSON with "ok": false, but curl still exits with code 0 because the request itself went through.

{"ok":false,"error_code":400,"description":"Bad Request: chat not found"}

Comparing uptime monitoring options

OptionChecked fromMinimum interval
UptimeRobot (free plan)The service's external servers5 minutes
Bash script on the VPS itselfThe same server as the siteAny, depends on cron
Uptime Kuma (self-hosted)Your own separate monitoring server20 seconds
ZabbixA dedicated monitoring server, supports agentsConfigurable, down to seconds

When monitoring from a single point is not enough

  • A bash script on the VPS itself will not notice the whole server going down — if the server itself fails, there is nothing left to run the check and send an alert. You need an external service like UptimeRobot checking from outside.
  • A single external checker can give a false alarm because of temporary issues in its own network — paid monitoring plans check from several geographic points and only alert when the outage is confirmed from multiple locations.
  • You need to monitor more than the HTTP code — page content or the response time of a critical API — a simple curl script only checks the status code; content checks need more specialized tools.
  • You need SLA reporting with months of incident history for clients or management — free tools usually keep history for a limited period; long-term reporting needs a paid plan or your own incident database.

Verifying the result

  1. Run the script manually and temporarily stop Nginx: systemctl stop nginx — a Telegram notification must arrive by the next cron run.
  2. Confirm cron is actually running the job: grep CRON /var/log/syslog | tail must show regular entries for the script's run.
  3. Make sure the script does not fire false alarms on brief network hiccups — add a retry before alerting if single false positives have already happened.
  4. Confirm that after the site recovers the system also sends a recovery notification, not just a failure one — otherwise it is easy to forget the issue was resolved long ago.

For monitoring the server's own resources, not just external site availability, see the article on Netdata. A self-hosted alternative to UptimeRobot with its own dashboard is covered in the article on Uptime Kuma.

Was this article helpful?
← Back to Knowledge Base Ask Support