How to Set Up Uptime Alerts That Actually Reach You

How to Set Up Uptime Alerts That Actually Reach You

Uptime monitoring alerts setup comes down to two independent jobs: a checker that decides whether your service is healthy, and a delivery path that reaches a human. Most outages that drag on for hours are not detection failures. The check fired. The notification landed in a mailbox nobody reads, or it was suppressed by a rule someone wrote months ago and forgot about. Fix the delivery path first, then tune the checks around it.

Start With What the Check Actually Sends

Almost every uptime monitor, whether it is a hosted service or something you run yourself, is an HTTP client on a timer. It opens a connection, sends a request, reads the response, and applies a rule. That is the whole mechanism. Everything else is scheduling and notification plumbing.

The rule matters more than the interval. A monitor that treats any response under 500 as healthy will happily report green while your application returns an error page with a 200 status. A monitor that treats a slow response as a failure will page you during a traffic spike that users never noticed. Decide what "up" means before you decide how often to check it. For a web application, that usually means a status code check plus a content check on a string that only appears when the page rendered correctly.

Run the check by hand first. If you cannot reproduce a healthy response from your own terminal, the monitor will not either, and you will spend the first hour of an incident debugging the monitor instead of the service.

curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' \
  --max-time 10 https://example.com/health

200 0.183

The -w flag writes the status code and total time to stdout while the body goes to /dev/null. That single line tells you whether the endpoint answers, how long it takes, and whether it times out at ten seconds. If your health endpoint returns JSON, pipe it through a parser and assert on a specific field rather than grepping for a substring. Substring checks break the moment someone changes a label in a template.

Choosing Channels That Reach a Person, Not a Folder

Email is the weakest channel and the one everyone configures first. It is asynchronous, it is easy to filter, and it fails silently when a mail server is the thing that went down. Keep it as a record, not as your primary pager.

A chat webhook is the next step up and costs nothing to add. Most chat platforms accept a POST with a JSON body, so you can wire it from a shell script, a cron job, or the monitor's own integration. Test the webhook before you trust it.

curl -sS -X POST "$WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d '{"text":"test alert from uptime check"}'

{"ok":true}

The strongest channel is one that makes noise on a device the on-call person is already carrying. That usually means a push notification or an SMS gateway. SMS has real delivery risk and real cost, so most teams reserve it for a second tier: chat first, SMS or a phone call if the incident is still open after a few minutes. Escalation is the feature that turns a notification into a response. A single channel with no escalation is a suggestion, not an alert.

Whatever you choose, send a test message through the full path today and confirm it arrives. Then send one at three in the morning, or set an alarm and check that the phone actually wakes you. A notification that arrives silently is the same as no notification.

Suppression, Flapping and the Alert You Never Saw

The most common reason an alert does not reach anyone is that a rule stopped it. Maintenance windows that were never closed, deduplication keys that swallowed a second failure, quiet hours applied to the wrong group, a filter that drops anything containing the word "test" in a hostname that happens to contain "test".

Audit your rules on a schedule, not after an incident. Read them as a list of reasons a page will not fire, and ask whether each one still applies. A maintenance window with no end time is an outage you have decided not to know about.

Flapping is the other silent killer. A service that goes down and up every ninety seconds will generate a page every ninety seconds until someone mutes the channel, and then it is muted forever. Require a failure to persist across consecutive checks before it pages, and require a recovery to persist before it clears. Two consecutive failures at a one minute interval is a reasonable starting point for most services. If your check interval is longer than your tolerance for downtime, shorten the interval rather than the threshold.

Set the check interval from your recovery target, not from habit. If you want to know within two minutes, a five minute interval cannot deliver that no matter how good the alerting is.

Run Your Own Checker When You Need Control

A hosted monitor is convenient because it checks from outside your network, which is exactly where you want the vantage point. But you can build the same thing with a script and a scheduler, and doing so teaches you what the hosted product is actually doing.

Write a script that exits non zero on failure, then let your scheduler or your alerting tool decide what to do with the exit code. Keep the script boring and make it log what it saw.

#!/bin/sh
# /usr/local/bin/check-site.sh
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 https://example.com/health)
if [ "$code" != "200" ]; then
  echo "FAIL: got $code" >&2
  exit 1
fi
echo "OK"

Then schedule it and let a wrapper handle the alert. The important part is the exit code contract: zero means healthy, anything else means something is wrong. That contract is what every monitoring system on the planet expects, and writing to it means you can swap the scheduler or the notifier later without rewriting the check.

Run the check from at least two locations if you can. A single vantage point cannot tell the difference between your service being down and the network path to it being down. Two independent checkers that disagree is a routing problem. Two that agree is your service.

Verify the Path End to End

The only way to know your setup works is to break something on purpose. Point a check at an endpoint you control, make it return a 500, and watch the whole chain: check fires, threshold is met, notification is sent, channel delivers, phone buzzes. Time it. If the gap between the failure and the buzz is longer than you thought, that gap is your real detection time, and it is the number that matters during an incident.

Do this once a quarter and after any change to your alerting rules. Then write down who is on call, what channel they watch, and what the escalation path is. An alert that reaches a person who does not know they are responsible is only marginally better than one that reaches a folder.

Your next step is small and concrete. Pick your most important service, run the curl check by hand, and confirm you can tell a healthy response from a broken one. Then wire that exact check to one channel, send a test, and verify it arrives on a device that will wake someone. Add the second channel and the escalation rule only after the first path is proven. Everything else is refinement.

Related articles

Subscribe to our newsletter

Get the latest hosting tips, performance insights, and industry news.