IoT device uptime monitoring: how to tell a dead device from a quiet one
A website is either answering or it isn't, and a dozen services will ping it every minute and tell you which. An IoT device is harder. It sits behind a router you don't control, it only speaks when it has something to say, and some of the time it's quiet on purpose. Monitoring IoT uptime comes down to one question: is this device dead, or just quiet? This guide covers the techniques that answer it: offline windows, heartbeats, last-will messages and probes. It also covers how to turn the answer into an availability number you can defend and an alert that people don't learn to ignore.
The ideas apply to any platform. The last section shows how Synacl does it, with the actual numbers.
Why website uptime tools don't fit devices
A website uptime monitor works by pulling. It sends a request from the internet and times the answer. Almost nothing in an IoT fleet can be monitored that way:
- Devices are behind NAT. A sensor on a factory Wi-Fi network or a 4G modem has no public address. It connects out to a broker and nothing can connect in.
- Devices push, on their own schedule. A temperature logger reporting every five minutes looks exactly like a dead one for four minutes and fifty-nine seconds.
- Some devices aren't on the network at all. A Modbus energy meter on an RS485 bus talks to a gateway, not the internet. If the meter dies, the gateway is still online and every network check says it's fine.
- "Last seen" isn't "up". A dashboard that shows "last seen 3 minutes ago" leaves every reader to decide for themselves whether that's normal. Uptime monitoring means writing that rule down once, per device.
So device monitoring is mostly inference from silence. You know how often a device should report, and when it goes quiet for longer than that, you conclude it's down. The rest of this guide is about making that inference correctly.
Four ways to know a device is alive
| Technique | How it works | Detects | Blind spot |
|---|---|---|---|
| Telemetry timeout | Every reading refreshes a "last seen" time; silence past a window marks it down | A device, or its whole path, has stopped delivering data | Needs a window that fits the reporting interval |
| Heartbeat | The device sends a small "I'm alive" message on a fixed schedule, separate from its data | A device that reports rarely or only on change | A heartbeat from a healthy MCU while the sensor itself has failed |
| MQTT last will (LWT) | The client registers a message at connect time; the broker publishes it if the connection drops uncleanly | Power loss or network drop, within about 1.5 × the keepalive | Only covers the connection, not whether the device is reading anything |
| Active probe | The platform polls the target: an HTTP request, a TCP connect, a Modbus read | Anything with an address the platform can reach | Useless behind NAT or on a private network |
In practice you combine them. Telemetry timeout is the default for everything because it costs nothing extra: the data you already send is the evidence. A heartbeat covers devices that report rarely or only when a value changes. LWT covers gateways, which keep a long-lived MQTT connection and should be flagged the moment it breaks. Probes are for the few things that have a reachable address, like a Modbus-TCP device polled from the cloud or an HTTP health endpoint.
Picking the offline window
The offline window is how long a device may stay silent before you call it down. It's the most important number in the whole system, and it's usually set wrong in one of two ways:
- Too short, and the device flaps. A device reporting every 60 seconds, judged against a 60-second window, will be marked offline every time a message is a second late. People start to ignore the alerts, and then they ignore a real one.
- Too long, and you find out tomorrow. A one-hour window on a freezer logger means the freezer has been warm for an hour before anyone hears about it.
A rule that holds up: about three missed reports, with a floor and a ceiling.
- Three times the interval absorbs one lost message and one late one without flapping. A 60-second reporter goes offline after about 3 minutes of silence, and a 5-minute reporter after about 15.
- A floor of around 90 seconds stops fast reporters from flapping on ordinary network jitter. A device reporting every 2 seconds doesn't need to be declared dead after 6.
- A ceiling of around an hour stops a slow reporter from hiding a failure for most of a shift. If a device only reports every few hours, give it a heartbeat or a shorter interval rather than a longer window.
Devices that report only on change (a door contact, a pump running signal) need a heartbeat. Without one, a door that stays shut all weekend is indistinguishable from a sensor with a flat battery.
Gateway down or device down?
Gateway-connected fleets have a layer that direct-to-cloud devices don't. When readings from forty Modbus meters stop at once, there are two very different explanations:
- The gateway is down. Its power, network or firmware failed. All forty meters are probably fine.
- The gateway is up but the meters aren't answering. The RS485 bus has a wiring fault, a meter lost power, or a unit ID changed.
A monitoring setup that can't tell these apart sends forty alerts for the first case and gets the second one wrong. Getting it right needs two separate signals:
- Gateway presence: the gateway's own connection, detected by its LWT and a periodic heartbeat. When the gateway drops, its devices should inherit that status at the same moment rather than each timing out on its own. Alert on the gateway going offline, not on every device under it, and one fault becomes one alert.
- Per-device read health: the gateway reports whether it actually managed to read each device. A read that failed while the gateway is online is a device problem. It deserves its own state, "unreachable", rather than the same "offline" as a dead gateway.
This split is what tells a technician whether to drive to the site with a replacement gateway or with a meter tester. On a small fleet that's most of the value of monitoring.
Measuring availability honestly
Once you have up and down events, availability looks like simple arithmetic: time up divided by total time. The trap is the time you don't know about:
- the days before the device was installed
- a period older than the history you keep
- a stretch where the monitoring system itself had a gap
Most tools quietly count unknown time as up, which is how a device installed three days ago ends up with "99.9% availability this month". The honest approach has three states, up, down and unknown, and leaves unknown out of the calculation entirely. It then shows how much of the period the figure is based on:
99.8% available · based on 62% of the period
When there's no evidence at all, the answer is "—". It isn't 100%, and it isn't 0% either.
For an SLA, turn the target into an error budget before you commit to it. Over a 30-day month:
| Target | Allowed downtime per 30 days |
|---|---|
| 99% | 7 h 12 min |
| 99.5% | 3 h 36 min |
| 99.9% | 43 min |
| 99.99% | 4 min 19 s |
Compare the budget with your offline window. With a 15-minute window, a shorter outage is never detected at all, and one that is detected lasts at least 15 minutes, so three of them spend a whole 99.9% budget. On devices that report every five minutes, that target can't really be measured. Set targets your detection method can actually resolve.
Two details make outage history trustworthy. Stitch outages across midnight so that one outage is one row, not two. And record why each one started: silence, a failed probe, or the device reporting itself down.
Alerts people don't learn to ignore
Detection is only useful if someone acts on it. Four rules keep offline alerts worth reading:
- Alert on the event, not the dashboard. Nobody watches a dashboard at 3 a.m. Tie a rule to the offline event with an email, push or webhook action.
- Scope rules to what they watch. An unscoped "any device offline" rule with a cooldown has a nasty failure mode: the first device to fail starts the cooldown, and every other failure during it is silenced. One rule per critical device or group, or rules that cool down per device, avoids that.
- Rely on the window, not extra delays. If the offline window is right, the event already means "confirmed silent". Stacking a second delay on top just makes you later.
- Send recoveries too. "Back online after 14 minutes" closes the loop, and a run of recoveries shows you which site has a flaky link.
Monitoring the things that aren't devices
Plenty of what a device fleet depends on isn't a device: the API it posts to, the broker, the cellular router, a shop's till, the nightly backup script. These fit the same model.
- Things with a public address get an HTTP or TCP probe: a status code, text the response must contain, or a JSON field such as
status: okon a/healthendpoint. Treat a response that's too slow as down. - Things behind a router get a heartbeat, also called a dead man's switch. A cron job calls a URL every few minutes, and silence marks it down. The machine can also report itself down explicitly, for example when the service it watches has failed but the machine hasn't. Then the outage records the actual cause, not just the silence.
Keeping these on the same uptime history as your devices matters more than it sounds. It lets you see that forty devices at one site went offline at the moment the site's router stopped checking in.
How Synacl does it
Synacl applies all of the above out of the box, and the numbers are published:
| How the device connects | Offline window |
|---|---|
| Through an ESP32 gateway (RS485, Modbus, I²C, GPIO, …) | 90 seconds. The gateway sends a presence heartbeat about every 10 seconds, so a device publishing every 5 minutes is still judged correctly |
| Polled by the platform (HTTP, SNMP, Modbus TCP) | 3 × the poll interval |
| Direct MQTT or webhook | 90 seconds by default, adjustable per device with a reporting grace period |
Every window is clamped between 90 seconds and one hour. Gateways use an MQTT last will plus a 60-second report. When a gateway goes offline, its devices are marked offline at the same moment, so a rule on gateway/offline gives you one alert per site. A device the gateway can't read while it's still online shows amber, "unreachable", not red. The online status article explains every state.
Availability is built from the same device/offline and device/online events as the event feed, so the uptime strip and the feed always agree. Synacl keeps up, down and unknown as separate states, shows the coverage next to every percentage, and stores one record per device per day, so history outlives the raw events. See uptime. Dashboards get an uptime bar strip, a status grid, an incident log and an SLA widget that tracks the error budget against the time there's evidence for.
For things that aren't Synacl devices, monitors give you HTTP and TCP probes (from a 20-second interval) and heartbeats with a URL and a secret. A heartbeat can send {"up": 0} to report itself down straight away, and it can carry extra numbers such as queue depth or backup age that you can chart. A failing monitor raises the same device/offline event as a device, so the rules you already have work on it unchanged. What each plan includes, from monitor count to how far back uptime history goes, is on the pricing page. The free plan includes a monitor.
If you haven't connected any hardware yet, ESP32 Modbus RTU to a cloud dashboard takes a real RS485 sensor from wiring to a live reading, which is the first thing there is to monitor.
Try it on your own hardware
Synacl is free for five devices — no card, no sales call. Flash a gateway from the browser, add your first device, and see live data in a few minutes.