Guide

How to Get Notified When a Server Goes Offline (Heartbeat Monitoring, 3 Working Setups)

Any alert script that lives on the server dies with the server. Three tested heartbeat setups that catch the silence, and where each one breaks.

PulseNode · updated July 2026

There is a cruel joke at the bottom of every self-monitoring setup: the script that is supposed to email you lives on the machine that just died. Whatever took the box down, a power cut or a kernel panic, took your alert with it. To get notified when a server goes offline, something outside the server has to notice that it went quiet. That inversion is called heartbeat monitoring, or a dead man's switch. Here are three setups that work, with commands I tested before publishing, and a hosted shortcut at the end.

The short version

Create a free check on healthchecks.io, then put one line in each server's crontab: * * * * * curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/<your-uuid>. When the pings stop, healthchecks.io messages you on Telegram, Slack, or email. The rest of this page covers why the direction matters, two other builds, and what each costs in upkeep.

Why your server can't tell you it's dead

Alerts that live on the box die with the box

The intuitive design is a script on the server that emails you when it spots trouble. That works for partial failures like high load or a crashed process. It fails exactly when the failure is total: a kernel panic stops cron, a power cut stops everything, and a full disk blocks the mail spool, which is its own well-documented way for a box to go silent. Total failure produces the one thing a local script can never report: silence.

Dead man's switch monitoring flips the direction

So flip it. The server sends a small "I am alive" signal on a fixed schedule, and an external listener raises the alarm when the signal stops arriving. From outside, a kernel panic and a pulled network cable look identical, which is the strength of the pattern: silence covers every failure mode at once.

Option 1: a cron heartbeat to healthchecks.io (free, ten minutes)

Create the check, then set Period and Grace

healthchecks.io gives you 20 checks on its free Hobbyist tier, no credit card. Each check is a unique ping URL with two settings: Period, the expected time between pings, and Grace, extra slack before the alarm. Per the official docs, notifications fire after Period plus Grace of silence, so a one-minute Period with three minutes of Grace means you know within about four minutes.

The one-line crontab entry

# Open the crontab on the server you want watched
crontab -e

# Ping your check every minute
* * * * * curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/your-uuid-here

The flags are the ones healthchecks.io recommends: -f turns an HTTP error into a nonzero exit, -sS keeps errors but hides progress noise, -m 10 caps the request at ten seconds, --retry 5 retries transient failures. I ran it before publishing: it exits 0 against a valid URL, and a bad UUID gets HTTP 400 and exit 22.

Debian and Ubuntu ship the cron package already. On the RHEL family, install it first with sudo dnf install cronie, then sudo systemctl enable --now crond. crontab -e works the same on both.

Hook up notifications

The free tier routes alerts to email, Telegram, Slack, Discord, Signal, ntfy, webhooks, and about 25 other integrations. SMS, WhatsApp, and phone calls are the exception: those credits exist only on Business tiers from $20/mo. The free tier also caps history at 100 log entries per check.

Prefer to self-host it?

Healthchecks itself is open source: BSD 3-Clause, Django, official Docker images, v4.2 as of April 2026, about 10k GitHub stars. The recursion to notice: your self-hosted instance is now the machine that must never go down, and it needs its own watcher. Run it in a different failure domain, or you have built a smoke detector that plugs into the burning house.

Option 2: a watcher script on a second box

The script

If you already run a second machine, you can poll from there and skip third parties. This script checks a target and messages you through the Telegram Bot API, which takes one curl with a chat_id and text. I tested both branches: a clean exit while the target is up, and the alert fired when the host was unreachable.

#!/usr/bin/env bash
# check-alpha.sh: runs on machine B, watches machine A.
# Alerts to Telegram after 3 failed checks in a row, once per outage.

TARGET="https://alpha.example.com/"     # any URL machine A answers
STATE="/var/tmp/check-alpha.fails"
LIMIT=3

TG_TOKEN="123456:your-bot-token"
TG_CHAT="your-chat-id"

if curl -fsS -m 10 --retry 2 -o /dev/null "$TARGET"; then
    rm -f "$STATE"
    exit 0
fi

fails=$(( $(cat "$STATE" 2>/dev/null || echo 0) + 1 ))
echo "$fails" > "$STATE"

if [ "$fails" -eq "$LIMIT" ]; then
    curl -s "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
        -d chat_id="${TG_CHAT}" \
        -d text="ALERT: ${TARGET} failed ${fails} checks in a row" \
        -o /dev/null
fi
chmod +x /usr/local/bin/check-alpha.sh
crontab -e

# On machine B, check machine A every minute
* * * * * /usr/local/bin/check-alpha.sh

The state file keeps this livable. One failed probe is usually a network blip, so the script waits for three consecutive failures, and the -eq comparison fires exactly once per outage rather than every minute. Recovery deletes the state file and re-arms it. One test note: --retry covers transient HTTP errors, but a DNS failure fails each attempt immediately; the alert branch still triggers.

Want a UI for this? Uptime Kuma

The polished version of the same idea is Uptime Kuma: MIT license, v2.4.0 from May 2026, about 88k GitHub stars, installed with Docker Compose on port 3001. Alongside HTTP, TCP, ping, and DNS monitors it has Push monitors, heartbeat checks where silence marks the target down, so one Kuma instance can be both your poller and your dead man's switch listener.

The catch: who watches the watcher

Machine B is now unmonitored infrastructure. When it reboots for updates, you are blind and nothing says so. When its network hiccups, you get paged for servers that are fine. The trade is fair when the second box already exists at a different provider and earns its keep. It is a real cost when you would rent a VPS purely to curl another VPS.

Why systemd watchdogs won't send a server down alert

WatchdogSec= restarts a hung service

With WatchdogSec= set, your service must call sd_notify() with WATCHDOG=1 at regular intervals once startup completes. Miss the window and systemd marks the service failed and kills it with SIGABRT; Restart=on-watchdog brings it back automatically. This unit passes systemd-analyze verify on systemd 257:

# /etc/systemd/system/my-app.service
[Unit]
Description=my-app with a process watchdog

[Service]
ExecStart=/usr/local/bin/my-app
WatchdogSec=30
Restart=on-watchdog

[Install]
WantedBy=multi-user.target

Configure this for any long-running daemon you build. But the chain is detect, kill, restart. Nothing in it messages a human.

RuntimeWatchdogSec= reboots a hung host

One level up, RuntimeWatchdogSec= in /etc/systemd/system.conf programs a hardware watchdog (/dev/watchdog0) to reboot the machine when the service manager stops checking in. It needs a real watchdog device, common on dedicated servers, absent on some VPSes. That is useful whole-host self-healing and still zero notification: after a power cut, nothing local could ever reach you. Watchdogs complement an external heartbeat; they cannot replace one.

The hosted shortcut: get notified when a server goes offline without running a watcher

Every setup above leaves you writing the heartbeat or hosting the listener. This section is the pitch, so weigh it as one. PulseNode's agent is a single static Go binary that pushes metrics out over HTTPS about every 30 seconds and never listens on a port. That schedule is a heartbeat by construction: when the pushes stop, PulseNode sends an agent-offline alert to your Telegram or email from its own servers. You get the dead man's switch without writing a cron line or keeping a second machine alive.

Setup is short but not zero: install the agent with one command (Linux, amd64 and arm64), then add a notification channel, either an email address or Telegram, connected in settings with no bot server to host. Once a channel is set, agent-offline alerting is active with no rule to create.

The same pushed data feeds threshold rules like cpu > 85% or disk > 90% (disk tracks your fullest mount), with per-rule cooldowns from 1 to 1440 minutes and recovery notices. The heartbeat tells you the server died; the metric history often tells you why, like a RAM chart climbing for six hours before the silence.

Where PulseNode falls short

It is a young product from a single founder, and it is hosted only: the source is closed and you cannot self-host it. If that rules it out, run Healthchecks or Uptime Kuma from above. There is no public API and no data export today. Website checks (HTTP and TLS expiry) are status-only on the dashboard and send no notifications; the offline alerting described here is the agent-offline alert. Delivery is Telegram and email, with no SMS paging.

Hobby is €5/mo for up to 5 servers with 7 days of history, Pro €15/mo for 20 servers with 30 days, billed through Lemon Squeezy, cancel anytime. If one box and the free healthchecks.io tier cover you, use that. PulseNode earns its fee across several servers, when offline and resource alerts should come from one agent nobody has to babysit.

One agent, offline alerts included

Install the agent, connect Telegram or email, and hear about it when any of your servers goes quiet.

Start monitoring for €5/mo → Pro: 20 servers for €15/mo

Which setup should you pick?

SetupDetects whole-host deathNotifies youMaintenanceCost
healthchecks.io cron heartbeat Yes (silence trips it) Yes: email, Telegram, Slack, more One cron line per server Free for 20 checks
Second-box watcher / Uptime Kuma Yes, while the watcher stays up Yes: whatever you wire in A second machine to run and patch The second box
systemd watchdogs Partly: restarts a service or reboots the host No, never Set once in unit files Free
PulseNode agent-offline alert Yes (push silence trips it) Yes: Telegram, email Install agent once, set a channel €5/mo for 5 servers

With one or two servers and a spare ten minutes, take the healthchecks.io free tier; it is the best value on this page. Homelab owners should look at Uptime Kuma first, since the second box already exists. PulseNode makes sense at several servers, when you want offline and resource alerts without hosting the listener. Configure systemd watchdogs regardless; self-healing belongs next to whichever alerting you pick.

See also

FAQ: getting notified when a server goes offline

How do I get notified when my server goes offline for free?

Create a free check on healthchecks.io (20 checks on the Hobbyist tier) and add a one-line cron job that pings it every minute. When the pings stop, you get an email, Telegram, Slack, or Discord message at no cost. Hosted tools like PulseNode bundle offline alerts with resource metrics, but for a zero budget the cron heartbeat is hard to beat.

What is a dead man's switch in server monitoring?

It is an alert that fires on silence instead of on a distress call. The server sends a small "I am alive" signal on a fixed schedule, and an external listener raises the alarm when the signal stops arriving. A dead machine cannot call for help, but it also cannot keep pinging, so any total failure trips the switch.

What is the difference between heartbeat monitoring and ping or uptime monitoring?

Ping or uptime monitoring polls from outside: a service probes your host and alerts when the probes fail. Heartbeat monitoring pushes from inside: the host reports in on a schedule and silence triggers the alert. Push traffic is outbound only, so it works behind NAT and strict firewalls, and it catches a box that still answers ping while cron and your services are dead.

Can systemd alert me when my server goes down?

No. WatchdogSec= restarts a hung service and RuntimeWatchdogSec= reboots a hung host through a hardware watchdog, and neither sends any notification. When power or network is gone, nothing on the machine can reach you anyway. Use watchdogs alongside an external heartbeat monitor, not instead of one.