IoT Tutorials

Grafana Alerts for IoT Sensor Data: Thresholds, Stale Sensors and Notifications

Build Grafana alert rules on MQTT sensor data in InfluxDB, with one alert instance per device, sensible pending periods, no-data handling for silent sensors and contact points, then compare them with broker-side threshold rules in ConnectMQ.

Grafana alerts for IoT sensor data firing on a temperature threshold from MQTT readings stored in InfluxDB
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

Grafana alerts for IoT sensor data turn a dashboard that someone has to watch into a system that tells you when something is wrong. In this tutorial you will create alert rules on MQTT sensor readings stored in InfluxDB: a per-device temperature threshold, a rule that catches sensors that stop reporting, and notification routing, followed by a comparison with the threshold rules built into the ConnectMQ portal.

Prerequisites

This guide builds on the stack from our TIG stack with Docker Compose tutorial, where Telegraf subscribes to MQTT topics on broker.connectmq.com and writes to InfluxDB 2. The data model is:

Element Value
Bucket sensors
Measurement sensor
Tags device, line
Fields temperature, humidity
Source topics connectmq/demo/<run-id>/<line>/<device>/telemetry

Any InfluxDB data source in Grafana 10 or 11 works the same way. If your data comes from a Python bridge instead, as described in storing MQTT data in InfluxDB, only the measurement name in the queries changes.

How Grafana Alerting Evaluates Rules

Grafana alerting runs on the Grafana server, not in your browser, and works independently of dashboards. Every rule follows the same pipeline:

  1. Query. Fetch recent data from the data source, for example the last ten minutes of temperatures.
  2. Expressions. Reduce each series to a single number, such as the last or mean value, and compare it against a threshold.
  3. Evaluation. The rule runs on a fixed interval defined by its evaluation group.
  4. Pending period. A condition must stay true for this long before the alert fires, which filters out single noisy readings.
  5. Notification. Firing and resolved alerts are routed through notification policies to contact points such as email, Slack, Microsoft Teams, Telegram or a webhook.

The most important property for IoT is that rules are multi-dimensional. If the query returns one series per device, Grafana creates one alert instance per device. A single rule therefore covers your entire fleet, and the notification tells you exactly which sensor is affected.

Rule 1: Per-Device Temperature Threshold

In Grafana, open Alerting, then Alert rules, then New alert rule.

Name: High temperature

Query A (InfluxDB data source, Flux):

from(bucket: "sensors")
  |> range(start: -10m)
  |> filter(fn: (r) => r._measurement == "sensor" and r._field == "temperature")
  |> group(columns: ["device", "line"])
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)

The group call is what makes the rule multi-dimensional: each device becomes its own series and its own alert instance. Averaging over one-minute windows smooths out measurement noise before the threshold is applied.

Expression B: Reduce. Input A, function Last, mode "Drop non-numeric values". This turns each series into its most recent one-minute average.

Expression C: Threshold. Input B, is above 30. Set C as the alert condition.

Folder and labels. Put the rule in a folder such as IoT and add a label severity=warning. Labels drive notification routing later.

Evaluation behaviour. Create an evaluation group called sensors-1m with an interval of 1 minute, and set the pending period to 5 minutes. The alert then fires only when a device has averaged above 30 degrees for five consecutive evaluations.

Annotations. Add a summary that names the device and value:

{{ $labels.device }} on {{ $labels.line }} is at {{ printf "%.1f" $values.B.Value }} °C

Click Save rule and exit. Within a minute, the rule list shows one instance per device in the Normal state.

Rule 2: Detect Sensors That Stop Reporting

A sensor that dies does not send a high value; it sends nothing. Threshold rules cannot catch that by themselves, and in practice silent sensors are among the most common IoT failures. There are two complementary approaches.

Option A: configure no-data handling

In every rule, the evaluation section has a setting for what happens when the query returns no data. The options are No Data, Alerting, Normal and Keep Last State. For a single-device rule, setting it to Alerting is enough. For a multi-dimensional rule it is not, because the query still returns data for the healthy devices, so a single silent device does not trigger a no-data state at all.

Option B: alert on data age per device

Compute how many seconds have passed since each device's last reading and alert when it grows too large:

from(bucket: "sensors")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "sensor" and r._field == "temperature")
  |> group(columns: ["device", "line"])
  |> last()
  |> map(fn: (r) => ({ r with _value: float(v: uint(v: now()) - uint(v: r._time)) / 1000000000.0 }))

Use Reduce Last as expression B and Threshold "is above 120" as expression C, with a pending period of 2 minutes. Pick the threshold from the device's publish interval: about four times the interval is a reasonable start, so a sensor that publishes every 30 seconds is flagged after two quiet minutes. A device that has been silent for more than the one-hour range disappears from the query entirely, so set this rule's no-data behaviour to Alerting as well, which catches the case where the whole fleet goes quiet.

Rule 3: Route Notifications

Create a contact point under Alerting, then Contact points. Slack, Microsoft Teams, Telegram and generic webhooks only need a URL or token. Email requires SMTP settings on the Grafana server; with Docker, add them as environment variables:

services:
  grafana:
    environment:
      GF_SMTP_ENABLED: "true"
      GF_SMTP_HOST: smtp.example.com:587
      GF_SMTP_USER: alerts@example.com
      GF_SMTP_PASSWORD: ${SMTP_PASSWORD}
      GF_SMTP_FROM_ADDRESS: alerts@example.com
      GF_SMTP_FROM_NAME: IoT Alerts

Then open Notification policies and add a child policy that matches severity=warning and sends to your contact point. Group notifications by alertname and line so that ten overheating sensors on the same line produce one message instead of ten. Use mute timings for planned maintenance windows when sensors are expected to go offline.

Test the Alert End to End

Do not wait for a real failure to find out whether alerts work. Publish elevated readings for one device with a unique test ID:

ID=a1b2c3
for i in $(seq 1 60); do
  mosquitto_pub -h broker.connectmq.com -p 1883 -i "alerttest-$ID" \
    -t "connectmq/demo/$ID/line1/sensor-test/telemetry" \
    -m "{\"device\":\"sensor-test\",\"ts\":$(date +%s%3N),\"temperature\":35.5,\"humidity\":40.0}"
  sleep 10
done

Within about a minute, the sensor-test instance moves to Pending. After the five-minute pending period it switches to Firing and the notification arrives. Stop the loop and two more things should happen: the high-temperature alert resolves, and after two quiet minutes the stale-sensor rule fires for sensor-test. That one test proves the full chain from broker to notification. The MQTT device simulator is useful for longer tests, since its faulty devices produce occasional spikes.

Tuning Checklist

  1. Smooth noisy signals with aggregateWindow before applying thresholds.
  2. Use a pending period of several evaluation intervals to ignore one-off spikes.
  3. Group by stable tags only, so each alert instance maps to a real device.
  4. Handle silence explicitly with a data-age rule and sensible no-data settings.
  5. Group notifications by line or site to avoid alert storms.
  6. Export finished rules to YAML from the rule's menu and keep them in version control, so a rebuilt Grafana can provision them from files.

Grafana Alerting vs ConnectMQ Threshold Alert Rules

ConnectMQ also offers threshold alert rules in its portal, with triggered alerts recorded in an alerts log. The two approaches sit at different points in the pipeline and complement each other.

Aspect Grafana alerting ConnectMQ threshold alert rules
Where it runs Grafana server, on stored data Broker portal, on incoming MQTT values
Requires a database Yes, such as InfluxDB No
Time-window logic Aggregations, pending periods, data age Simple thresholds on values
Notification routing Contact points and policies Alerts log in the portal
Setup effort Higher, part of a TIG stack Low, configured in the portal
Best for Trends, fleet-wide rules, on-call routing Quick visibility during commissioning and small deployments

A practical combination is to use the portal's threshold rules while devices are being commissioned and no database exists yet, and to add Grafana rules once history and on-call notifications matter. Both read the same topics; neither requires changes to the devices.

For the ingestion side, the Telegraf MQTT consumer guide explains the input configuration in detail, and the MQTT client libraries guide helps when you write device code. Grafana's own alerting documentation covers every rule option.

Get Started with ConnectMQ

You can build and test these alerts today using the public MQTT test broker and simulated data. For production, run your devices on a hosted MQTT broker with TLS and private credentials. ConnectMQ gives you that broker plus a portal with a live topic explorer, dashboard and threshold alert rules. Create a free Serverless broker at app.connectmq.com with no credit card and connect Telegraf with the generated credentials.

Frequently Asked Questions

Can one Grafana alert rule cover all my IoT sensors?

Yes. Group the query by a device tag and Grafana creates a separate alert instance for each device, all from a single rule.

How do I alert when a sensor stops sending data?

Calculate the age of each device's last reading in the query and alert when it exceeds a few publish intervals. No-data handling alone does not catch one silent device in a multi-device rule.

What pending period should I use for sensor alerts?

Start with three to five evaluation intervals. Shorter periods react faster but produce more false alarms from noisy readings.

Do I need Grafana if my broker already has threshold alerts?

Not for simple thresholds. Grafana becomes valuable when you need trends, time windows, data-age checks and routing to on-call channels.

Related articles

Best MQTT CLI Tools for Testing, Scripting and Debugging

A hands-on comparison of mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, the MQTT.js CLI, curl and mqttui, with the same test run against broker.connectmq.com so you can choose the right tool for scripting and debugging.

8 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.