Building sovereign IoT monitoring with Grafana and InfluxDB? WZ-IT plans, runs and integrates the full open-source stack on your infrastructure - from sensor to dashboard. To the Grafana IoT platform - Book a consultation
You build a sovereign Grafana IoT dashboard with InfluxDB in six steps: set up InfluxDB as the time-series database, write IoT data into it via MQTT and Telegraf (or from ThingsBoard), connect InfluxDB to Grafana as a data source, create the dashboard and panels, and finally define alerts. The whole stack is open source and runs self-hosted on your own infrastructure (Proxmox, Hetzner or on-premises) - with no cloud lock-in and no per-device license. Current building blocks (as of October 2026): Grafana OSS 13.2.x under AGPLv3, InfluxDB 3 Core (v3.12) or InfluxDB OSS 2.x, and Telegraf 1.40.2 as the data collector.
Table of contents
- Architecture: data flow from sensor to dashboard
- Which InfluxDB version to choose
- Step 1: Set up self-hosted InfluxDB
- Step 2: Write IoT data via MQTT and Telegraf
- Step 3: Forward ThingsBoard data to InfluxDB
- Step 4: Connect Grafana as a data source
- Step 5: Build the dashboard and panels
- Step 6: Configure alerts
- What it costs: self-hosted vs. Grafana Cloud
- Run your Grafana IoT stack with WZ-IT
- Further guides
Architecture: data flow from sensor to dashboard
The proven self-hosted IoT stack consists of four decoupled building blocks, each with one clear job:
- Sensors and gateways send telemetry over MQTT to a broker.
- The MQTT broker (e.g. Mosquitto) receives the messages and decouples senders from receivers.
- Telegraf subscribes to the topics, parses the payload and writes it into InfluxDB as the time-series database.
- Grafana reads InfluxDB as a data source and visualizes the data in dashboards and alerts on thresholds.
In the layered IoT architecture, InfluxDB sits on the platform/persistence layer and Grafana on the application layer. The key benefit of this separation: every block is replaceable and none locks you into a proprietary format. You can later swap Telegraf for Node-RED, scale the broker, or replace InfluxDB with another time-series database without rebuilding the dashboard.
Which InfluxDB version to choose
In 2026, InfluxData offers several lines in parallel. The choice determines license, long-term storage and query language:
| Variant | License | Best for | Query languages |
|---|---|---|---|
| InfluxDB 3 Core (v3.12) | MIT / Apache 2.0 | single-node, recent data, edge; no compaction | SQL, InfluxQL |
| InfluxDB 3 Enterprise | commercial (free home tier) | long-term, compaction, HA, multi-node | SQL, InfluxQL |
| InfluxDB OSS 2.x | MIT | self-hosted IoT with long-term storage, still maintained | Flux, InfluxQL |
InfluxDB 3 Core is the open-source single-node build (dual-licensed under MIT/Apache 2.0, github.com/influxdata/influxdb). It is optimized for recent data and, per the vendor, lacks compaction and long-term optimization - ideal for the edge and short retention. InfluxDB 3 Enterprise adds compaction, historical queries and high availability (influxdata.com); for non-commercial home use there is a free single-node license (two cores), while commercial use is paid. For many self-hosted IoT projects that need real long-term history, InfluxDB OSS 2.x (MIT, Flux + InfluxQL) is still the most pragmatic, stable choice - it remains maintained per the roadmap and is not deprecated. The steps below use InfluxDB 2.x; the InfluxDB 3 path is nearly identical, only the query language switches from Flux to SQL/InfluxQL.
Step 1: Set up self-hosted InfluxDB
The simplest way to run the stack is containerized. A minimal docker-compose.yml for InfluxDB plus Grafana:
services:
influxdb:
image: influxdb:2.9
ports: ["8086:8086"]
environment:
DOCKER_INFLUXDB_INIT_MODE: setup
DOCKER_INFLUXDB_INIT_USERNAME: admin
DOCKER_INFLUXDB_INIT_PASSWORD: "change-me"
DOCKER_INFLUXDB_INIT_ORG: wz-it
DOCKER_INFLUXDB_INIT_BUCKET: iot
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: "my-super-secret-token"
volumes:
- influx-data:/var/lib/influxdb2
grafana:
image: grafana/grafana:13.2.3
ports: ["3000:3000"]
volumes:
- grafana-data:/var/lib/grafana
volumes:
influx-data:
grafana-data:
Since version 12.4, Grafana publishes new Docker images only as grafana/grafana; the grafana/grafana-oss repository is no longer updated (Grafana docs). The influxdb:2.9 image contains the current 2.x line (v2.9.1). After docker compose up -d, InfluxDB is reachable on port 8086. Three concepts matter: the organization (wz-it), the bucket (iot, the database for your series) and the API token that Telegraf and Grafana use to write and read. In production, create separate tokens per job with minimal scope (a write-only token for Telegraf, a read token for Grafana) and put TLS in front via a reverse proxy.
Step 2: Write IoT data via MQTT and Telegraf
Telegraf (currently v1.40.2, released 12 October 2026, MIT license) is the standard agent for moving MQTT telemetry into InfluxDB. The mqtt_consumer input plugin subscribes to topics, and the influxdb_v2 output plugin writes to InfluxDB. A lean telegraf.conf:
[[inputs.mqtt_consumer]]
servers = ["tcp://mosquitto:1883"]
topics = ["sensors/#"]
username = "telegraf"
password = "change-me"
data_format = "json_v2"
[[inputs.mqtt_consumer.json_v2]]
[[inputs.mqtt_consumer.json_v2.field]]
path = "temperature"
type = "float"
[[outputs.influxdb_v2]]
urls = ["http://influxdb:8086"]
token = "my-super-secret-token"
organization = "wz-it"
bucket = "iot"
If a sensor publishes JSON like {"temperature": 21.7} to sensors/hall1/temp, the value lands as a series named mqtt_consumer with a temperature field in the iot bucket. The topic is stored automatically as a tag, so you can later filter per device or hall. If you need richer transformation, protocol translation or enrichment, place Node-RED between broker and database instead of or alongside Telegraf. The influxdb_v2 output works identically against InfluxDB 3, since its write API is v2-compatible.
Step 3: Forward ThingsBoard data to InfluxDB
If you already run ThingsBoard as your IoT platform, there are three clean ways to also get its telemetry into InfluxDB and Grafana:
- In parallel via Telegraf (decoupled): Since the devices publish over MQTT anyway, let Telegraf read the same topics and write to InfluxDB. ThingsBoard and InfluxDB both receive the raw data without affecting each other.
- Via the Rule Engine: In the ThingsBoard rule chain, a REST API call or MQTT node forwards telemetry to Telegraf or directly to the InfluxDB write API. That way only selected, already processed values flow into the time-series database.
- Straight from the database: ThingsBoard stores telemetry in PostgreSQL/TimescaleDB depending on setup. Grafana can read this directly through its built-in PostgreSQL data source, with no second database.
Which path fits depends on whether Grafana only complements ThingsBoard or InfluxDB becomes the leading history. For pure long-term monitoring, we prefer the decoupled Telegraf variant.
Step 4: Connect Grafana as a data source
Grafana ships with the InfluxDB data source built in, so no plugin is needed (grafana.com). In the Grafana UI:
- Open Connections > Data sources > Add data source > InfluxDB.
- Choose the query language:
Fluxfor InfluxDB 2.x,SQLorInfluxQLfor InfluxDB 3. - Enter the URL:
http://influxdb:8086. - Set authentication: for Flux the organization, token and default bucket; for InfluxQL/SQL the database/bucket name and the token.
- Click Save & test - Grafana confirms the connection.
Use a dedicated read token with minimal scope for Grafana, not the admin token from setup.
Step 5: Build the dashboard and panels
Create your first panel via Dashboards > New > New dashboard > Add visualization and select the InfluxDB data source. A time-series panel for the average temperature looks like this in Flux (InfluxDB 2.x):
from(bucket: "iot")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "mqtt_consumer" and r._field == "temperature")
|> aggregateWindow(every: v.windowPeriod, fn: mean)
Grafana fills the v.timeRangeStart, v.timeRangeStop and v.windowPeriod variables automatically from the time picker and panel width, so the query adapts to the selected range. For InfluxDB 3 you use InfluxQL or SQL instead, e.g. SELECT mean(temperature) FROM mqtt_consumer WHERE $timeFilter GROUP BY time($interval).
Proven panel types for IoT:
- Time series for trends (temperature, pressure, throughput).
- Stat and Gauge for current single values with threshold coloring.
- State timeline for on/off or status sequences.
- Table for the latest raw readings per device.
With dashboard variables (e.g. a device variable fed from the topic tags) a single dashboard becomes reusable across the whole fleet instead of being duplicated per machine.
Step 6: Configure alerts
Since the 9.x releases, Grafana uses Unified Alerting that runs directly on the data sources - self-hosted, with no extra service. To set up an alert for excessive temperature:
- Under Alerting > Alert rules > New alert rule, define an InfluxDB query as the condition (e.g. mean of the last 5 minutes).
- Set a threshold expression such as
IS ABOVE 60. - Choose a pending period (e.g. 2 minutes) so short spikes do not alert immediately.
- Pick the target via Contact points: email, Slack, Telegram, webhook or PagerDuty.
- Use notification policies to control which alerts go to which team.
This gives you a complete, vendor-neutral alerting chain from threshold to notification - without an external monitoring SaaS.
What it costs: self-hosted vs. Grafana Cloud
The self-hosted stack is free on the software side: Grafana OSS under AGPLv3, InfluxDB 3 Core under MIT/Apache 2.0 or InfluxDB OSS 2.x under MIT, Telegraf under MIT. What remains are operating costs (server, storage, maintenance). The cloud alternatives bill differently:
| Model | Cost (as of October 2026) | Data sovereignty |
|---|---|---|
| Self-hosted OSS stack | server + ops only, no license | full EU data sovereignty |
| Grafana Cloud Free | EUR 0: 10,000 active series, 3 users, 14 days retention | with Grafana Labs |
| Grafana Cloud (paid) | usage-based by series/GB | with Grafana Labs |
| InfluxDB 3 Enterprise | commercial (free home tier) | depends on hosting |
Grafana Cloud is convenient for small setups, but the free tier is tightly capped (10,000 series, 14 days retention, grafana.com/pricing). With the high series counts and long history typical of IoT, usage-based cloud tiers scale up quickly and the data sits outside your control. Self-hosted keeps the bill predictable and the telemetry in the EU on your infrastructure. We dig into this trade-off in IoT self-hosted vs. cloud.
Run your Grafana IoT stack with WZ-IT
Grafana, InfluxDB, Telegraf and MQTT together form an open, vendor-neutral monitoring stack - the ideal basis for sovereign IoT without cloud lock-in and without a per-device license. At WZ-IT we plan the edition and version choice (InfluxDB 3 vs. 2.x, retention, sizing), deploy the stack containerized on your infrastructure in the EU (Proxmox, Hetzner or on-premises), harden it with TLS, scoped tokens and backups, and build the dashboards and alerting chains for your specific use case. You keep data, tokens and operations in your hands. More on our Grafana expertise and in the IoT hub.
Set up a self-hosted Grafana IoT dashboard with InfluxDB? To the Grafana IoT platform - Book a consultation
Further guides
- What is MQTT? - the protocol that delivers the data to the broker
- IoT architecture: the layers explained - where InfluxDB and Grafana sit
- What is ThingsBoard? - platform alternative and data source
- Grafana expertise - dashboards and alerting in production
- Node-RED expertise - process MQTT data and route it to InfluxDB











