ThingsBoard IoT Platform Tutorial: From Devices to Live Dashboards
This ThingsBoard IoT platform tutorial takes you from an empty install to a working pipeline: a device publishing telemetry over MQTT, a rule chain that stores readings and raises alarms, and a dashboard that shows it all live. ThingsBoard is one of the most widely deployed open-source IoT platforms, and it bundles device management, a visual rule engine, and a dashboard builder in one stack. That combination is why teams reach for it when they want results in an afternoon, not a sprint.
We will run the Community Edition (CE) with Docker, provision a single device, push a JSON payload with mosquitto_pub, route that message through the rule engine, and bind a chart and an alarm table to the data. Every command here is plausible and correct in form; a few payload values are illustrative and marked as such. No prior ThingsBoard experience is assumed, only basic Docker and MQTT familiarity. The goal is not a toy hello-world but a mental model you can scale: by the end you will understand why ThingsBoard separates transport from core from rule engine, and how that separation is exactly what lets a laptop demo grow into a clustered deployment without a rewrite.
What this covers: architecture, install, device provisioning over MQTT, a four-node rule chain, a live dashboard, and the gotchas that bite first-time operators.
What ThingsBoard Is and Why
ThingsBoard is an open-source platform for data collection, processing, visualization, and device management. People reach for it because it collapses three jobs that usually mean three separate tools — an MQTT broker plus ingestion service, a stream-processing engine, and a visualization stack — into one cohesive product with a web UI on top. You can stand up a working telemetry pipeline without writing a backend, and you can extend it with code when you need to. Architecturally it splits into a few cooperating layers, and understanding them up front saves hours of confusion later. Figure 1 shows how the pieces connect.
To appreciate what that buys you, picture building the same thing by hand. You would run an MQTT broker, write an ingestion service that authenticates devices and parses payloads, stand up a time-series database with a schema, build a stream processor for thresholds and alerts, and then write a frontend with live charts and a websocket layer. Each piece is a project. ThingsBoard ships all of them pre-integrated and configured through a UI, which is why a single engineer can demonstrate an end-to-end pipeline in an afternoon. The trade is the usual one for an integrated platform: less freedom in any single layer, in exchange for not having to glue five systems together yourself.
The Transport layer terminates device protocols. ThingsBoard ships MQTT, HTTP, and CoAP transports out of the box, plus LwM2M and SNMP. A device speaks its native protocol to the transport, which normalizes every message into an internal envelope and hands it to the core. MQTT is the most common choice for telemetry because it is lightweight, connection-oriented, and built for the publish/subscribe pattern that fits sensor data. The MQTT specification, maintained by OASIS, defines those publish/subscribe semantics that ThingsBoard relies on. The key design point is that the transport is the only part of the system that knows or cares about wire protocols — everything downstream sees the same normalized message, so a CoAP device and an MQTT device flow through identical rule chains.
The Core owns entities and session state. In ThingsBoard everything is an entity: devices, assets, customers, dashboards, and the relations between them. A device is a physical or virtual thing that sends telemetry. An asset is a logical grouping — a building, a production line, a fleet — that you attach devices and other assets to. Telemetry is time-series data (temperature, voltage, RPM) stored against an entity; attributes are key-value metadata that change rarely, like firmware version or location. Relations wire entities into a graph, so you can model “this device belongs to that line, which belongs to this plant,” and walk that graph in a rule chain or dashboard. Getting this entity model right early pays off, because dashboards and rules built against an asset hierarchy generalize far better than ones hard-wired to individual devices.
The Rule Engine is where ThingsBoard stops being a database and starts being a platform. Every inbound message flows through a rule chain, a directed graph of nodes that filter, transform, enrich, persist, and react to data. Think of it as a visual, message-driven pipeline: a message enters, hops from node to node along labeled relations, and triggers side effects — saving data, sending an email, calling a REST endpoint, raising an alarm — along the way. This is the programmable heart of the system, and we build one in Step 2.
Sitting above all of this is the web UI and REST API, which serve dashboards and expose every entity for automation. Anything you can do by clicking in the UI you can also do over REST, which matters once you start provisioning devices in bulk or wiring ThingsBoard into a larger system. The official ThingsBoard documentation is the authoritative reference for each layer, and recent ThingsBoard versions keep this separation stable enough that the concepts below port across releases.
One more architectural idea ties the platform together: multi-tenancy. A single ThingsBoard install hosts many tenants, each with isolated devices, rule chains, and dashboards, and each tenant can expose dashboards to its own customers. This is why ThingsBoard shows up so often in product companies that ship a connected device and want to give every buyer a portal — the isolation is built in rather than bolted on. For a single team running internal infrastructure you simply ignore the extra layers and live inside one tenant, which is what we do here.
The flow we are about to build follows the same path every message takes through these layers, so it is worth fixing in your head before you touch a command. A device authenticates to the transport and publishes a JSON payload. The transport validates the credential, resolves the session to a device entity, and normalizes the payload into an internal message. The core hands that message to the rule engine, which runs it through the active rule chain — saving telemetry, evaluating conditions, raising alarms. The results land in the database, and the web layer streams them to any open dashboard over a websocket. Three layers, one direction of flow, and every step in this tutorial is just an instance of that pattern. When something does not work, asking “which layer dropped it?” is almost always faster than guessing.

Figure 1: ThingsBoard platform architecture — transports normalize device protocols, the core manages entities, the rule engine processes messages, and the web layer serves dashboards.
Prerequisites and Setup (Working Steps)
You need a Linux host (Ubuntu 22.04 or later works well), Docker, and the Docker Compose plugin. A 2 vCPU, 4 GB RAM machine is plenty for this tutorial. You also need the mosquitto-clients package for the publish step later.
Install the MQTT client tools first:
sudo apt-get update
sudo apt-get install -y mosquitto-clients
The fastest way to get ThingsBoard CE running is the official single-node Docker image with a Postgres database. Create a docker-compose.yml:
version: "3.8"
services:
thingsboard:
image: thingsboard/tb-postgres
container_name: thingsboard
ports:
- "8080:9090" # web UI / REST API
- "1883:1883" # MQTT transport
- "7070:7070" # Edge RPC (optional)
- "5683-5688:5683-5688/udp" # CoAP transport
environment:
TB_QUEUE_TYPE: in-memory
volumes:
- tb-data:/data
- tb-logs:/var/log/thingsboard
restart: always
volumes:
tb-data:
tb-logs:
The tb-postgres image bundles ThingsBoard and Postgres in one container, which is ideal for learning. For production you split the database out and switch the queue to Kafka — more on that in the scaling section. Figure 2 shows how the components talk.
A word on the port mapping, because it trips people up. The container exposes the web UI and REST API on internal port 9090, which the compose file publishes as 8080 on your host. The MQTT transport listens on 1883, the standard unencrypted MQTT port, and CoAP uses the UDP range. In production you would not expose 1883 directly — you front it with 8883 over TLS — but for a local tutorial the plain port keeps the publish commands short. If another service already holds port 8080 or 1883 on your machine, change the left side of the mapping rather than the right, since the right side is what ThingsBoard listens on inside the container.
Bring the stack up:
docker compose up -d
docker compose logs -f thingsboard
The first boot installs the database schema and seeds demo data, so give it a couple of minutes. When the logs settle, open http://localhost:8080. Log in with the default tenant administrator account that the demo install creates:
Username: tenant@thingsboard.org
Password: tenant
Change that password immediately — default credentials are the single most common way a learning install ends up exposed. ThingsBoard has three built-in roles: the system administrator manages tenants and platform settings, the tenant administrator manages devices, rule chains, and dashboards inside one tenant, and the customer user gets a read-mostly view of whatever entities you assign to them. You will work as the tenant administrator throughout this tutorial.
A note on the queue setting. The compose file sets TB_QUEUE_TYPE to in-memory, which keeps everything in a single process with no external broker. That is perfect for learning and small demos. It is also the first thing you outgrow: an in-memory queue does not persist across restarts and cannot spread load across nodes. We come back to this in the scaling section, but keep it in mind as the one knob that separates “laptop demo” from “production cluster.”

Figure 2: Component and data flow — devices connect through a transport, the core persists entities, the rule engine routes messages, and dashboards read back time-series data.
Step 1: Provision a Device and Connect Over MQTT
A device in ThingsBoard needs two things before it can send data: a device entity in the platform, and credentials it presents on connect. The default and simplest credential is an access token — an opaque string the device uses as its MQTT username.
In the web UI, open Entities → Devices and click the plus button to add a new device. Name it weather-station-01, leave the device profile as default, and save. The device profile is worth a glance here: it is a template that defines transport settings, alarm rules, and which rule chain inbound messages route to. Every device you create points at a profile, so configuration you set once on a profile applies to every device that uses it. For now the default profile is fine.
Open the device, go to the Details tab, and click Manage credentials. ThingsBoard auto-generates an access token; copy it. The credentials dialog also offers X.509 certificate and MQTT Basic options — we use the token here for speed, but note where the stronger choices live. For this walkthrough assume the token is A1_TEST_TOKEN_xxx (yours will differ).
Now publish telemetry. ThingsBoard’s MQTT transport expects telemetry on the reserved topic v1/devices/me/telemetry, with the access token supplied as the MQTT username and the password left empty. Figure 3 traces the round trip.
mosquitto_pub \
-h localhost -p 1883 \
-u "A1_TEST_TOKEN_xxx" \
-t "v1/devices/me/telemetry" \
-m '{"temperature": 22.4, "humidity": 61, "battery": 3.71}'
The payload is a flat JSON object of key-value pairs. ThingsBoard timestamps each reading on arrival and stores all three keys as separate time-series series against weather-station-01. If you want to control the timestamp yourself — useful for backfilling — wrap the values:
mosquitto_pub \
-h localhost -p 1883 \
-u "A1_TEST_TOKEN_xxx" \
-t "v1/devices/me/telemetry" \
-m '{"ts": 1717830000000, "values": {"temperature": 23.1, "humidity": 58}}'
Go back to the device, open the Latest telemetry tab, and you should see temperature, humidity, and battery with their current values. That confirms the full path worked: transport authenticated the token, the core resolved it to your device, and the default rule chain saved the data.
If nothing shows up, three things go wrong most often. The token is mistyped (it is case-sensitive). The topic is wrong — it is literally v1/devices/me/telemetry, where me is a placeholder the transport resolves from the token, not your device name. Or the payload is not valid JSON. A loop gives you a steady stream to watch on the dashboard later:
while true; do
TEMP=$(awk "BEGIN{srand(); print 20 + rand()*15}") # illustrative value
mosquitto_pub -h localhost -p 1883 -u "A1_TEST_TOKEN_xxx" \
-t "v1/devices/me/telemetry" \
-m "{\"temperature\": $TEMP, \"humidity\": 60}"
sleep 5
done
Telemetry is not the only thing a device sends. Devices publish attributes — slow-changing metadata such as firmware version — on v1/devices/me/attributes, and they can subscribe to shared attributes the server pushes down, which is the basis for remote configuration. ThingsBoard also defines an RPC topic pattern so the server can call a method on the device and get a reply, the mechanism behind a “reboot” or “set setpoint” button on a dashboard. We stay with telemetry for this tutorial, but knowing these channels exist tells you where two-way control lives when you need it.
Provisioning one device by hand in the UI is fine for learning, but it does not survive contact with a real fleet. For more than a handful of devices, drive provisioning through the REST API. The pattern is a single authenticated call per device that creates the entity and returns its credentials, which you then flash or hand to the device:
# Illustrative: create a device and read back its access token
curl -X POST "http://localhost:8080/api/device?accessToken=A1_TEST_TOKEN_xxx" \
-H "Content-Type: application/json" \
-H "X-Authorization: Bearer $JWT" \
-d '{"name": "weather-station-02", "type": "default"}'
Better still for unattended rollouts is device provisioning, where the firmware ships with only a shared provisioning key and secret, not a per-device token. On first boot the device calls a provisioning endpoint, ThingsBoard mints a unique credential, and the device caches it for all future connections. This keeps secrets out of your firmware images and lets you revoke a single device without touching the rest of the fleet. It is the right pattern the moment “the fleet” stops being something you can configure by clicking.

Figure 3: Device to transport to core sequence — the MQTT transport authenticates the access token, resolves the device session, and forwards the normalized message to the rule engine.
Step 2: Build a Rule-Engine Pipeline
By default ThingsBoard saves telemetry through a built-in Root Rule Chain, but the real power is editing that flow. A rule chain is a graph: messages enter at a node, and each node emits the message on one or more labeled relations (Success, Failure, True, False) that wire to the next node. Figure 4 shows the chain we build.
Open Rule Chains in the left menu and edit the Root Rule Chain. The default chain already contains a Message Type Switch node connected to a Save Timeseries node. We extend it to raise an alarm when temperature crosses a threshold. Our chain has four meaningful nodes.
1. Message Type Switch. This is the entry filter. Every inbound message carries a type — POST_TELEMETRY_REQUEST for telemetry, POST_ATTRIBUTES_REQUEST for attributes, and so on. The switch routes each type down a different relation. Telemetry leaves on the Post telemetry relation.
2. Save Timeseries. A persistence node. It writes the message’s time-series keys to the database against the originating device. Wire the Post telemetry relation into it so every reading is stored. This node is why your Latest telemetry tab populated in Step 1.
3. Script (Filter) node. Add a filter → script node to test a condition. It runs a small JavaScript function that returns True or False, and the message exits on the matching relation. For a high-temperature check:
// Returns true when temperature exceeds the alarm threshold
return msg.temperature !== undefined && msg.temperature > 30;
Wire the Post telemetry relation from the switch into this filter as well, so telemetry both gets saved and gets evaluated.
4. Create Alarm. Connect the filter’s True relation to a Create Alarm node. Configure it with an alarm type like High Temperature and a severity such as MAJOR. ThingsBoard deduplicates: a repeated breach updates the existing active alarm rather than spamming new ones, and a Clear Alarm node on the False path closes it when the reading recovers. This active/cleared lifecycle is what makes the alarm table on the dashboard useful — operators see what is wrong right now, not a wall of historical noise.
A few other node families are worth knowing even though we do not wire them here. Transformation nodes rewrite the message payload or metadata — handy for unit conversion or renaming keys before storage. Enrichment nodes pull in related data, such as a device’s attributes or its parent asset, so a downstream node can make decisions with more context. Action nodes reach outside ThingsBoard: send an email, post to a webhook, push to a Kafka topic, or call an external REST service. Most real pipelines are a handful of these strung together, and because the whole thing is a visual graph, a new engineer can read the data flow without reading code.
Save the chain. Publish a value above the threshold to test it:
mosquitto_pub -h localhost -p 1883 -u "A1_TEST_TOKEN_xxx" \
-t "v1/devices/me/telemetry" -m '{"temperature": 34.5}'
A High Temperature alarm now appears under the device’s Alarms tab. The Debug mode toggle on any node shows the exact inbound and outbound message, metadata, and any script errors — turn it on while building, then off in production because debug events are written to the database and add load.
It is worth understanding what actually moves between nodes, because that is where most confusion lives. Each message has three parts: a payload (the JSON your device sent), metadata (key-value context such as the device name, type, and timestamp), and a message type (like POST_TELEMETRY_REQUEST). Nodes read and write these parts. A transformation script, for example, gets both msg and metadata and can return a modified version of either. A common pattern is to enrich a reading with the parent asset’s name before saving, so a downstream alarm email can say “Line 3 overheated” instead of quoting a raw device UUID. You wire an enrichment node before the save node, and it copies the asset attribute into metadata for everything that follows.
The other thing to internalize is that relations are the control flow. There is no implicit ordering — a node only runs because an upstream node emitted a message on a relation that connects to it. Two relations from one node create a fan-out, where the same message travels both paths independently. That is exactly what we did above: the switch fans telemetry to both Save Timeseries and the Script Filter, so a single reading is stored and evaluated in parallel. Once relations click, the visual editor stops feeling like a toy and starts feeling like a dataflow language.
Consider one more realistic extension to see how the pieces compose. Suppose a low battery should also raise an alarm, but at a lower severity than overheating. You add a second Script Filter that returns true when msg.battery < 3.4, wire the switch’s Post telemetry relation into it, and connect its True relation to another Create Alarm node configured with type Low Battery and severity MINOR. Now a single reading can be saved, checked for high temperature, and checked for low battery, all in parallel, each path raising its own independent alarm. This is the everyday shape of a production rule chain: a small set of filters fanning off a switch, each ending in a save, an alarm, or an outbound action. Nothing about it requires you to write a service — you are drawing a graph.
A note on where rule logic should live. Simple thresholds belong in the rule chain, as above. But resist the urge to push heavy business logic into Script nodes, because those run per message and become a throughput tax at scale. For anything expensive or stateful, use an Action node to hand the message to an external service over REST or Kafka, and let that service do the work. The rule engine is a router and a triage layer first; treat it as a place for orchestration, not for your entire application.

Figure 4: Rule chain — the message type switch routes telemetry to a save-timeseries node and a script filter, which raises an alarm when the temperature threshold is breached.
Step 3: Build the Dashboard
A dashboard in ThingsBoard is a collection of widgets, each bound to one or more entity data sources through an entity alias. The alias is the bit of indirection that makes dashboards reusable: instead of hard-coding a device, you bind widgets to an alias, then point that alias at a device, an asset, or a filtered set of entities. Swap the alias target and the whole dashboard re-aims at different hardware. We build a dashboard with a real-time chart, a value card, and an alarm table for weather-station-01.
Open Dashboards, create a new dashboard called Weather Station, and click Add widget.
Time-series chart. Pick the Charts bundle and choose Time series chart. In the widget’s data configuration, set the entity alias to your device. Create an alias of type Single entity → Device → weather-station-01, then add the data keys temperature and humidity from the timeseries source. Set the time window — the picker at the top right of the dashboard controls it — to Last 15 minutes with real-time updates enabled. Save the widget. With your publish loop running, the line moves on screen as new points arrive, because ThingsBoard pushes telemetry to the dashboard over a websocket rather than polling.
It helps to understand the two kinds of data a widget can request, because choosing wrong is a common source of empty charts. Latest telemetry returns only the most recent value of each key — perfect for a gauge or value card. Timeseries returns a history of values across the selected time window — what a trend chart needs. A time-series chart bound to a latest-telemetry source shows a single point and looks broken; a value card bound to a timeseries source works but wastes bandwidth. Match the data source type to the widget, and most “the dashboard is empty” problems disappear.
Latest values card. Add a Cards → Value card widget bound to the same alias and the battery key, using the latest-telemetry source. This gives an at-a-glance current reading next to the trend chart, and it updates in real time over the same websocket the chart uses.
Alarm table. Add an Alarm widget → Alarms table. Point its data source at the same device alias. The table lists active and cleared alarms with type, severity, originator, and timestamps — so the High Temperature alarm you triggered in Step 2 shows up here, and clears automatically when the temperature drops back under 30. The alarm widget supports inline acknowledgement and clearing, so an operator can take ownership of an alarm directly from the dashboard, and that action flows back through the rule engine like any other event.
Each widget exposes an advanced settings tab where you control the visual details: axis ranges, colors, decimal precision, units, and thresholds. For the temperature series, set a red threshold line at 30 so the chart visually reinforces the same boundary your rule chain enforces. Keeping the dashboard threshold and the rule-engine threshold in sync is a small discipline that prevents the confusing situation where the chart looks alarming but no alarm fired, or vice versa. When the two agree, the dashboard becomes self-explanatory: the line crosses red, the alarm row turns orange, and an operator needs no training to read it.
To verify the whole pipeline end to end, run the publish loop, drop a single above-threshold value into the stream, and watch all three widgets react together — the chart spikes, the value card updates, and a new row appears in the alarm table within a second or two. That round trip, from mosquitto_pub on your terminal to a colored row in the browser, is the entire ThingsBoard value proposition in one observable motion.
Arrange the three widgets, save the dashboard, and you have a live operations view: trend on the left, current battery top-right, alarms underneath. To share it, assign the dashboard to a Customer and create a customer user; they see only the entities you assign, which is how multi-tenant ThingsBoard isolates one client’s data from another’s.
Two refinements make a dashboard feel finished. First, dashboard states let one dashboard drill from an overview into a per-device detail view — click a row in a table and the dashboard navigates to a state filtered to that device, all without building a second dashboard. Second, dashboard variables and the time-window selector let a single layout serve a whole fleet: the same chart and alarm table re-render for whichever device the operator picks. Building for an asset alias rather than a single device from the start is what unlocks this, which is why the entity model discussed earlier matters in practice and not just in theory.
That is the full loop — device to transport to rule engine to database to dashboard — running on a single laptop. From here, scaling is mostly an infrastructure exercise rather than a rewrite, because the entities, rule chains, and dashboards you built carry over unchanged to a clustered deployment.
Trade-offs, Gotchas, and What Goes Wrong
The access token model is convenient but coarse. A token is a bearer credential: anyone who has it can publish as that device, and there is no built-in expiry. For real deployments, prefer X.509 certificate credentials or MQTT Basic auth over TLS, and never ship a fleet that shares one token, because a single leaked credential then compromises every device. Rotate credentials through the REST API rather than the UI when you have more than a handful of devices, and consider device provisioning — ThingsBoard supports a flow where a device claims its own credentials on first connect using a provisioning key, so you never bake per-device secrets into firmware images. Figure 5 shows where this matters as you scale.
Rule-chain debugging is the second common pain point. A message can silently die because a node emitted it on a relation that goes nowhere — there is no error, the data just vanishes. Keep debug mode on while building, watch the event feed on each node, and remember that an unwired Failure relation drops messages. Script nodes that throw also route to Failure, so a typo in your filter can quietly stop alarms from firing.
Scaling the transport is where the single-container setup ends. The in-memory queue in our compose file does not survive a restart and does not scale horizontally. Production ThingsBoard runs the transports, core, and rule engine as separate microservices with Kafka as the message queue, so you can add transport nodes to absorb more device connections independently of core throughput. Each MQTT connection holds a persistent session, so connection count, not just message rate, drives transport sizing — ten thousand devices each sending one message a minute is a very different load profile from a hundred devices each sending a thousand. Size the transport tier for concurrent connections and the core tier for message throughput, and watch rule-chain complexity, because an expensive script node multiplied across millions of messages becomes your bottleneck before the database does.
Database choice is a quieter gotcha. The bundled setup stores time-series in Postgres, which is fine to a point but is not built for very high-cardinality, high-rate sensor data. Larger ThingsBoard clusters move time-series storage to Cassandra or a time-series-optimized store while keeping entity data in Postgres. Switching later is possible but disruptive, so if you already know your ingest rate will be high, pick the right backend before you accumulate a year of history in the wrong one.
Finally, CE versus PE. Community Edition gives you everything in this tutorial — device management, the full rule engine, dashboards, and multi-tenancy. Professional Edition adds white-labeling, advanced role-based access control, a scheduler and report generation, and prebuilt platform integrations for the major clouds and LoRaWAN networks. If your roadmap needs per-customer branding or fine-grained permissions, budget for PE early rather than rebuilding later. The good news is that the concepts and most of the configuration are identical across editions, so a CE prototype is genuine preparation for a PE deployment rather than throwaway work.

Figure 5: Scaling topology — load-balanced transport nodes feed a Kafka queue, the rule engine and core scale as a cluster, and a separate database tier holds time-series and entity data.
Practical Recommendations
Treat the single-container install as a sandbox only. The moment you move past experiments, split the database out, switch the queue from in-memory to Kafka, and front the MQTT transport with a load balancer. Decide your credential strategy before you provision device number two — retrofitting X.509 onto a fleet that shipped with shared tokens is painful.
Model your entities deliberately. Group devices under assets that mirror your physical hierarchy, so a dashboard built for one production line generalizes to the next with an entity alias swap rather than a rebuild. Use device profiles to define alarm rules and default rule-chain routing once, instead of per device.
Version-control what you can. Rule chains and dashboards both export to JSON, and ThingsBoard’s REST API lets you push them back in. Treat those exports like code: keep them in a repository, review changes, and promote them from a staging install to production rather than hand-editing the live system. The same goes for device profiles. This discipline is what separates a ThingsBoard deployment you can reason about from one where nobody remembers why a particular rule node exists. It also makes disaster recovery a restore rather than a rebuild, because the entity definitions live somewhere other than the one database you are trying to recover.
Quick checklist before you call a ThingsBoard deployment ready:
- [ ] Default
tenant@thingsboard.orgpassword changed - [ ] Devices use X.509 or per-device tokens, never a shared token
- [ ] MQTT transport behind TLS on port 8883
- [ ] Queue switched from in-memory to Kafka for any non-trivial load
- [ ] Database split from the application container
- [ ] Debug mode disabled on production rule nodes
- [ ] Alarm rules defined in the device profile, not duplicated per device
- [ ] Dashboards assigned to customers with least-privilege access
FAQ
What MQTT topic does ThingsBoard use for telemetry?
Devices publish to the reserved topic v1/devices/me/telemetry. The literal word me is a placeholder; the transport resolves it to the actual device from the access token supplied as the MQTT username. Attributes use v1/devices/me/attributes, and RPC has its own topic patterns.
Is ThingsBoard free?
ThingsBoard Community Edition is open source and free to self-host, and it covers everything in this tutorial. Professional Edition is a paid license adding white-labeling, advanced permissions, scheduling, and integrations. Both share the same core concepts, so skills transfer cleanly.
How does a device authenticate to ThingsBoard?
The default is an access token presented as the MQTT username. ThingsBoard also supports X.509 certificate credentials and MQTT Basic authentication (client ID, username, password). For production fleets, certificate-based credentials over TLS are the recommended approach.
What is a rule chain?
A rule chain is a directed graph of nodes that every inbound message passes through. Nodes filter, transform, enrich, persist, and react to data, emitting messages on labeled relations like Success, True, or Failure. It is the programmable processing layer that turns ThingsBoard from a database into a platform.
Can ThingsBoard scale to many devices?
Yes, but not in the single-container form shown here. Production deployments run transport, core, and rule-engine services separately with Kafka as the queue, letting each tier scale independently. Connection count and message rate both drive sizing, so plan transport capacity around concurrent sessions.
How do I see live data on a dashboard?
Bind a time-series chart widget to a device entity alias and the telemetry keys you want, then set a real-time time window. ThingsBoard streams updates to the dashboard over a websocket, so the chart moves as new telemetry arrives without manual refresh.
Further Reading
- Real-Time Asset Tracking with MQTT 5.0 and InfluxDB 3.0 Tutorial — a complementary end-to-end telemetry pipeline.
- Unified Namespace (UNS) Reference Architecture — how to structure ThingsBoard data inside a plant-wide namespace.
- MQTT Protocol: The Complete Technical Guide — the transport ThingsBoard depends on, explained in depth.
- ThingsBoard official documentation — authoritative reference for every node, transport, and API.
- OASIS MQTT specification — the standard the MQTT transport implements.
Riju builds and writes about industrial IoT, digital twin, and PLM systems. More background on the about page.
