The boring $5 tool that tells me when a server goes down
Published: July 22, 2026
You run a couple of backends, a database, a frontend, maybe a small server on Hetzner or some VPS. One of them falls over on a Sunday afternoon. How do you find out? Is it the client calling you? Or you happening to open the site? Or catching it in the server dashboard you keep? That is not monitoring. That's luck.
The piece that is usually missing is a channel that reaches your phone the second something is wrong, through Do Not Disturb if it is serious, without you building an app or paying for a heavy enterprise pager. I did not know a clean answer to this existed until a few weeks ago. It is called Pushover, it has been around since 2012, it costs a one-time $5, and it has quietly become the thing that tells me when a backend dies, a TLS cert is about to expire, or someone logs in from an IP that is not me.
The one-line version
Pushover is a "send a notification to my phone" button that any script or server can press with a single web request. Your code makes the request, a notification shows up on your phone a second later. That is the whole product.
How it actually works
The flow goes one way, your side makes one outbound call to Pushover, you are never waiting for them to reach into your server. Three hops:
- Something on your side notices a problem. That something is just code you already control, a cron job that pings your backend every couple of minutes, your app's error handler, a small monitoring script.
- That code makes one outbound HTTPS POST to Pushover's API, carrying a title, a message, and a priority.
- Pushover's servers get it and push it to the Pushover app on your phone. They own all the hard delivery machinery, the device registry, the Apple and Google push plumbing, the retry logic, the sounds.
So when people say it lives on their server, that is true in the useful sense, all the delivery machinery is theirs and hosted. You never run a notification server, never touch push certificates, never keep a device list. Your only job is the one outbound POST. Picture it as your code, one POST, Pushover's cloud, your phone.
The one-time setup
The setup is about ten minutes, done once.
- Install the app and get your two keys. Install Pushover on your phone and create an account, which registers the phone as a device. Then in the web dashboard create an application. You now have two strings, a user key that identifies you and an app token for the script, and your code sends messages using those two, no OAuth and no SDK, just the values and an HTTPS POST. It is free for a 30 day trial, after which it is not free, a one-time $4.99 per platform covers it (iOS, Android and desktop are billed separately, per Pushover's pricing page).
- Flip one phone-side toggle. To let emergency alerts ring through Do Not Disturb, grant the app notification permission and turn on its critical-alert override, once. That is the permission step people vaguely remember.
- Keep the two keys out of your source code. Put them in an environment variable or a secrets file like any other credential. Mine sit in an env file the cron jobs read, never in git.
A representative snippet
Here is the entire integration, in shell:
curl -s -X POST https://api.pushover.net/1/messages.json \
--data-urlencode "token=YOUR_APP_TOKEN" \
--data-urlencode "user=YOUR_USER_KEY" \
--data-urlencode "title=Backend down" \
--data-urlencode "message=vigil API failed its liveness check" \
--data-urlencode "priority=1"
Or the same thing from JavaScript, say inside a Cloudflare Worker or a Node service that just caught an error:
await fetch("https://api.pushover.net/1/messages.json", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
token: env.PUSHOVER_APP_TOKEN,
user: env.PUSHOVER_USER_KEY,
title: "5xx spike",
message: "api.tigzig.com returning 500s",
priority: "1",
}),
});
That single call is the whole thing. Everything else, which alerts fire, how loud they are, deduplication, recovery, is just your own logic around when to make the call.
The priority dial
The one feature I lean on most is the priority dial, which runs from -2 to 2 and decides how loud each alert is:
- priority -2, silent. No sound, no vibration, a pure log entry on the phone.
- priority -1, quiet. Shows up, no sound, look when you look.
- priority 0, normal. A normal buzz, respects your quiet hours.
- priority 1, high. Buzzes through quiet hours, even at night, look soon.
- priority 2, emergency. This is the one that keeps ringing. It re-alerts on a repeat interval and does not stop until you physically open the app and acknowledge it. If you sleep through the first buzz it rings again. It needs two extra parameters,
retry(how often to re-ring, minimum 30 seconds) andexpire(give up after, maximum 10,800 seconds, three hours, and Pushover caps it at 50 retries either way). I run retry 60 and expire 3600, so an unacknowledged emergency rings once a minute for up to an hour.
You can also set a different sound per alert type, so after a while you know the cert one from the CPU one by ear without looking. I am still on default sounds, that is a knob I have not turned yet.
Where I actually use it
I run more than 50 apps on tigzig.com across two servers, and Pushover is wired across the whole fleet. Here are some of the things it watches, each one a small script that makes that one POST when it detects its thing, grouped by how loud I made each.
Emergency, priority 2, rings until acknowledged, the get-out-of-bed tier:
- Host CPU alarm, the box's CPU pegged or a load spike.
- 4xx velocity auto-block, a single IP hammering the API fast enough to auto-jail it.
- Public API liveness outage, a backend failing its synthetic health probe.
- Public API 5xx alarm, real callers getting 500s in the logs.
High, priority 1, buzzes through quiet hours, the look-soon tier:
- Edge velocity jail, an IP got auto-jailed at the Cloudflare edge. The alert carries a deep link straight to the jail dashboard, since Pushover lets you attach a URL and a button to a message.
- Operator-range anomaly, activity from an IP outside my tight expected range, the "is that actually me" login check.
Quiet, priority -1, the FYI tier:
- New user feedback, someone left feedback in an app. I want to know, it is not a fire.
Normal, priority 0, the all-clear tier:
- Recovery pings, when a firing alert clears I get a quiet RECOVERED message with the outage duration, so I know it is back without going to check.
It also quietly backs the TLS cert expiry warnings (warn under 21 days, critical under 7, because an expired origin cert silently takes a site down) and the public status-page rollup. The value here is that one simple channel, but by picking a priority per event it becomes a proper tiered pager, some events barely make a sound and the serious ones keep ringing until you answer.
The one pattern worth adding on top
A naive setup fires the same alert every time the cron runs, so a three hour outage becomes ninety identical buzzes. I added a small active_alerts table. The first time a problem is seen I insert a row and fire the Pushover, on every run after that the insert is a no-op because a unique key blocks the duplicate, so it stays silent. When the problem clears I delete the row and send one quiet RECOVERED with the outage duration. Net effect, one alert when it breaks, one when it heals, nothing in between. That fire-once-and-recover pattern is the single most useful thing to add on top of raw Pushover, and it is about fifteen lines of glue.
The brain behind it: the monitoring dashboard
A related note, Pushover is only one part of the monitoring story .. it's just the notification arm. The brain behind it is a monitoring dashboard I built for myself and for my clients, the Tigzig Command Center.
There are great off-the-shelf tools for this (Grafana, Prometheus), but I wanted something exactly to how I think. It started last year as a tiny logging service and a single page, and grew over many months into what I run now.
It pulls everything into one view: live edge traffic, CF worker logs, down to the individual IP, which IPs and which /24 subnets are getting blocked, errors as they happen, the kinds of attacks landing through the day, TLS certs about to expire, and a lot more, tab by tab.
The eye-opener from watching at the IP level and raw hit level: the large majority of what hits a public endpoint is bots, scanners, crawlers, AI agents, and outright attackers, not real users. Actual human raw hits, in the territory of 1-3%.
Self-hosting, and the alternatives
A common question is whether you can self-host it. Pushover itself, no, it is a hosted service with its own phone apps and its own connection to Apple and Google's push networks, you cannot run the Pushover server. If self-hosting is a hard requirement the two well known open source options are ntfy (ntfy.sh), which you can self-host and which has its own phone apps, and Gotify, a self-hosted server with its own Android app.
One point worth knowing, and it runs against the obvious instinct. For the specific job of "tell me my server is down", a hosted notifier like Pushover is the safer choice. If you self-host your notifier on the same infrastructure you are monitoring, then when the box or the network dies your notifier dies with it, and the one message you most needed, "I am down", never gets sent. A hosted independent service has no shared fate with your servers, so it can still deliver the bad news while your own stuff is on fire. Self-host the notifier only if you have a compliance reason to keep the message content in house, and even then, run it somewhere independent of the thing it watches.
On credibility, Pushover is a small, long-lived, boring-in-a-good-way company. It turned ten in 2022 and has been going since 2012. One-time purchase, no subscription for basic phone use, and a generous allowance of 10,000 messages a month for free, shared across all the applications on your account. For a solo dev or a small business it is one of those rare tools that is cheap, does one thing, and has not let me down. Bigger teams reach for heavier pager platforms like PagerDuty or Opsgenie, with on-call schedules and escalation policies, Pushover is the right-sized tool below that tier.
I almost built this myself
A bit of story here. I actually started building my own version of this with Claude Code before I looked around. I'd assumed this kind of thing might be enterprise level .. or require configuring some complex platform.
Explored with Claude Code only ... Pushover came top of list and building my own stopped making sense. Top reasons:
- The economics. A one-time $5 for 10,000 messages a month. To build and run my own? My hourly rate is many multiples, am swamped and turning back potential clients. Easy no.
- The time. The build is simple, sure. But then you test it, you babysit it, something crashes at the wrong moment. No desire to take that on for an already-solved problem.
- The infrastructure. I already run two servers that are critical to me, plus another two dedicated to clients, and just keeping those monitored and secure is a real job. A third box to host my own notifier (Oracle free tier, maybe) is one more thing to harden. Go serverless instead and that's its own headache.
Pushover is zero headache.
The idea is this: just because you can build it doesn't mean you should. As a one-man show it's an easy call. For a big team the math might be different.
Send warnings, keep the secrets out
One rule I would keep whatever else you do. Every message passes through Pushover's servers and lands on your phone's lock screen, so the message should say something needs your attention, go look, and it should never carry the sensitive thing itself. No API keys, no passwords, no customer data in the body. My alerts are pointers, "5xx spike on X", "cert expiring", "IP jailed, open the dashboard", and where I want the detail I attach a link to my own authenticated dashboard rather than putting it in the notification. A lost or stolen phone then leaks a doorbell rather than a filing cabinet.
You can just ask your AI to wire it
You do not really need to study any of this. Pushover is standard enough that any current AI coding assistant already knows it cold. Tell your agent to add a Pushover alert when this backend fails its health check and it will drop in the exact POST above, wire it to your env vars, and you are done. I did not have to read a new doc to set mine up, the agent already knew how, the same way it knows how to send an email. If you want to go deeper the official docs are genuinely good and linked below, but the barrier to entry is close to zero.
The bigger capabilities I do not use
For completeness, here is the ceiling. I use the simple ninety percent case, one recipient, the priority dial, a deep link, dedup and recovery. The rest of the surface, in case you need it:
- Multiple devices and device targeting, register phone, tablet and desktop and send an alert to one specific device.
- A desktop and browser client, so alerts hit your laptop too.
- Delivery groups and Pushover for Teams, fan one alert out to a whole team with per-user routing, the step toward on-call without a full pager platform.
- Inactivity monitors, a Pushover for Teams feature that pages you when an expected check-in goes silent, a dead man's switch for the job that was supposed to run and did not. I do not have this on my plan and it is the one piece I wish I did, since today I run a separate heartbeat monitor to cover the same gap.
- Emergency receipts and acknowledgement callbacks, for priority 2 alerts you can query who acknowledged and when, and have Pushover POST back to your own server the moment it is acknowledged. That is the classic inbound-webhook direction, which I do not currently use.
- Webhook receivers, a Pushover-hosted URL you point a system at when it can only POST arbitrary JSON and does not speak the Messages API, and Pushover turns that JSON into a notification. Added in early 2026.
- Custom and uploaded sounds, a distinct tone per alert class.
- Image attachments, attach a screenshot or a graph to the notification, up to 5 MB.
- Message formatting, HTML or monospace and extra clickable URLs in the body.
- The Glances API, push tiny data points to a phone or watch widget, a lightweight always-on readout separate from notifications.
- The Subscriptions API, let other people subscribe to your application's notifications, which turns Pushover into a light broadcast channel.
- Message TTL, have a notification auto-delete after N seconds so stale alerts clean themselves up.
Roughly, I use it as a personal pager. It can also be a team pager, a broadcast channel, a desktop notifier, and a watch-face data feed.
Cost, once more
It is free for a 30 day trial, after which it is not free, a one-time $4.99 per platform covers it with no subscription on top. You get 10,000 free messages a month across your apps, and the company has been going since 2012. For a small builder it is about the best money-to-value ratio in the whole ops toolbox.
Links, for those who want the manual
- Main site: https://pushover.net
- The messages API, the one POST: https://pushover.net/api
- Emergency priority and receipts: https://pushover.net/api#priority
- Glances API: https://pushover.net/api/glances
- Subscriptions API: https://pushover.net/api/subscriptions
- Self-host alternatives: ntfy (https://ntfy.sh), Gotify (https://gotify.net)