n8n talks to MQTT through two core nodes: the MQTT Trigger, which subscribes to topics and starts a workflow for every incoming message, and the MQTT node, which publishes messages from any step of a workflow. Add an MQTT credential with your broker's host, port and login, drop in a trigger, activate the workflow and every sensor reading can fan out to Slack, email, a database, an HTTP API or back to a device.
This tutorial builds two real workflows — a temperature alert and a webhook-to-device command — and shows how to test each step with a second MQTT client.
How n8n fits into an MQTT system
n8n is a workflow automation tool, not a broker. It connects to your broker as an ordinary MQTT client:
| Role | n8n piece | MQTT action |
|---|---|---|
| React to device data | MQTT Trigger node | SUBSCRIBE to one or more topic filters |
| Send commands or derived data | MQTT node | PUBLISH to a topic |
| Glue | Any other node (IF, Switch, HTTP Request, Code, Slack…) | — |
That means everything you know about MQTT clients applies: each trigger needs a unique client ID, QoS is negotiated per subscription, and the broker's ACLs decide what n8n may read and write. If you already use Node-RED, the model is similar; see Node-RED and MQTT for the comparison point. n8n's strength is the long list of SaaS integrations sitting next to the MQTT nodes.
Run n8n locally
The quickest way to experiment is the official Docker image:
docker volume create n8n_data
docker run -it --rm --name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8nOpen http://localhost:5678, create the owner account and start a new workflow. n8n Cloud works the same way; the only difference is that the broker must be reachable from the internet, because the MQTT connection is opened from n8n's servers, not from your laptop.
Create the MQTT credential
Add any MQTT node, open Credential to connect with and choose Create new credential. The MQTT credential has these important fields:
| Field | Value for a TCP test | Value for TLS |
|---|---|---|
| Protocol | mqtt | mqtts |
| Host | broker.connectmq.com | broker.connectmq.com |
| Port | 1883 | 8883 |
| Username / Password | your broker credentials | your broker credentials |
| Client ID | leave empty or set a unique value | same |
| Clean Session | on | on |
Use TLS (mqtts on 8883) for anything beyond a quick test: the credential is stored once and reused by every node, so there is no reason to send passwords in clear text. n8n tests the connection when you save — if it fails, the error text is usually the broker's CONNACK reason. Look it up in the MQTT reason codes tool.
Workflow 1: temperature alert
The first workflow listens for sensor readings and posts a message when a value crosses a threshold.
Step 1 — MQTT Trigger. Set Topics to testmqtt/n8n/+/temperature. The field accepts a comma-separated list, and the + and # wildcards work as usual (check your filters with the topic matcher). Under Options, enable JSON Parse Body so the payload is parsed into an object, and enable Only Message if you do not need the topic in later steps. Keep the topic when one workflow handles many devices.
With both options as shown, a message arrives as an item like this:
{
"topic": "testmqtt/n8n/greenhouse-1/temperature",
"message": { "value": 31.4, "unit": "C", "ts": 1760700000 }
}Step 2 — IF node. Add a condition: number {{ $json.message.value }} is larger than 30.
Step 3 — Notify. On the true branch add a Slack, Telegram, Discord or Send Email node. A useful message text is:
🌡 {{ $json.topic.split('/')[2] }} is at {{ $json.message.value }} °{{ $json.message.unit }}The split('/')[2] picks the device ID out of the topic, which is why a consistent layout pays off — see topic design best practices.
Test it before activating
Click Execute workflow (or Listen for test event on the trigger). The trigger now waits for one message. Publish a reading from a terminal or from the online MQTT client:
mosquitto_pub -h broker.connectmq.com -p 1883 \
-t testmqtt/n8n/greenhouse-1/temperature \
-m '{"value": 31.4, "unit": "C", "ts": 1760700000}'The workflow executes once and you can inspect the data on every node. Publish a second message with "value": 22 to confirm the false branch stays silent.
Workflow 2: webhook to device command
The opposite direction is just as common: something outside the MQTT world (a form, a calendar, a CRM event, another API) should switch a device.
- Webhook node, method
POST, pathlamp. Its test URL looks likehttp://localhost:5678/webhook-test/lamp. - IF node that checks a shared secret header, for example
{{ $json.headers['x-api-key'] }}equals a value you store in n8n — do not let anyone on the internet publish to your devices. - MQTT node with Topic
testmqtt/n8n/lamp-1/set. Turn Send Input Data off and set Message to{{ $json.body.state }}. Under options choose QoS 1, and leave Retain off for momentary commands.
With Send Input Data on, n8n publishes the whole input item as JSON — handy for forwarding, but usually too much for a device that expects ON or OFF.
Watch the command topic in one terminal and call the webhook in another:
mosquitto_sub -h broker.connectmq.com -p 1883 -t 'testmqtt/n8n/+/set' -vcurl -X POST http://localhost:5678/webhook-test/lamp \
-H 'Content-Type: application/json' \
-H 'x-api-key: change-me' \
-d '{"state": "ON"}'Terminal 1 should print testmqtt/n8n/lamp-1/set ON. For the reverse pattern — MQTT messages that call an HTTP endpoint — see MQTT to webhook.
Activate the workflow
Test executions only run while the editor is listening. To process messages permanently, save the workflow and activate (publish) it. From then on n8n keeps the subscription open in the background and every message creates an execution you can review in the executions list.
Two settings matter once traffic is real:
- Execution volume. Every message is one execution. A sensor publishing once per second creates 86,400 executions a day, which fills the execution history and costs CPU. Aggregate at the edge, publish less often, or subscribe to an "events" topic rather than raw telemetry.
- Ordering. The trigger processes messages in parallel by default. If order matters (state changes for the same device), turn parallel processing off in the trigger options so messages are handled one after another.
Delivery guarantees and restarts
n8n is a client, so its delivery guarantees are the broker's guarantees for that subscription:
- QoS 0 messages published while n8n is restarting are lost.
- QoS 1 with a persistent session (Clean Session off and a fixed client ID) lets the broker queue messages while n8n is down and deliver them on reconnect. That only works on a broker that keeps sessions — the shared test endpoint
broker.connectmq.comdoes not store offline sessions, so try this against your own private broker instance. - Retained messages are delivered immediately when the trigger subscribes, so an activated workflow may fire once for every retained topic it matches. That is often what you want for state topics and a surprise for alert topics; see retained messages.
If you run n8n in queue mode with several workers, triggers still live on the main instance. Do not start multiple main instances with the same active MQTT workflow, or each message is processed several times.
Troubleshooting checklist
| Symptom | Likely cause | Fix |
|---|---|---|
| Credential test fails with "Not authorized" | Wrong username/password or the user lacks CONNECT rights | Check the login with mosquitto_pub/mosquitto_sub first |
| Trigger connects but never fires | Topic filter does not match, or ACL denies subscribe | Publish to the exact topic from the online client; check ACLs |
Expressions return undefined | JSON Parse Body is off, payload is a string | Enable the option or parse in a Code node |
| Workflow fires twice per message | Two active workflows or two n8n instances subscribe | Deactivate duplicates; use one main instance |
| n8n Cloud cannot connect | Broker only reachable on your LAN | Use a broker with a public endpoint and TLS |
Watch your n8n topics in the browser
n8n turns MQTT messages into workflows without writing a service: one trigger, a few nodes and an MQTT publish cover most alerting and command use cases. Test each workflow with a second client before activating it, give n8n its own restricted broker user, and keep high-frequency telemetry out of workflows so execution counts stay sane.
Frequently asked questions
Does n8n have a built-in MQTT node?
Yes. n8n ships two core nodes: the MQTT Trigger, which subscribes to one or more topics and starts a workflow for every message, and the MQTT node, which publishes a message from inside a workflow. Both share the same MQTT credential.
Why does my n8n MQTT Trigger only fire while I am testing?
In the editor, 'listen for test event' only runs while the editor is open. For permanent processing the workflow must be activated (published). Only an active workflow keeps its MQTT subscription open in the background.
Can n8n parse JSON MQTT payloads automatically?
Yes. Enable the 'JSON Parse Body' option on the MQTT Trigger and the message field becomes an object, so expressions like {{ $json.message.temperature }} work. Without it the payload arrives as a string.



