Managed MQTT Cloud

MQTT Vendor Lock-In: How to Keep Your Devices Portable With Standard MQTT

MQTT is an open standard, yet IoT projects still get locked in. The cause is rarely the protocol; it is reserved topics, proprietary auth, vendor SDKs and logic that lives inside one platform. Here is how to stay portable.

Illustration of avoiding MQTT vendor lock-in, with devices connected by standard MQTT able to switch between interchangeable brokers
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

MQTT vendor lock-in sounds like a contradiction, because MQTT is an open OASIS standard. Yet many IoT teams discover that moving their devices to another provider would mean rewriting firmware. This article explains where lock-in actually comes from, which proprietary extensions create it, and the concrete design rules that keep your devices portable across any standard MQTT 3.1.1/5.0 broker.

The Protocol Is Open; the Surroundings Are Not

MQTT itself is defined by the OASIS MQTT 3.1.1 and 5.0 specifications, published at mqtt.org. Any compliant client can talk to any compliant broker: connect, publish, subscribe, QoS, retained messages, will messages and, in MQTT 5, properties such as session expiry, message expiry, topic aliases and response topics.

Lock-in creeps in through everything around the protocol:

  • Reserved, platform-defined topics that devices must use.
  • Proprietary authentication flows that only one platform understands.
  • Vendor device SDKs that wrap MQTT in platform-specific concepts.
  • Server-side logic such as rules, routes or transformations written in a platform's own language.
  • Platform state services like shadows or twins that devices rely on.
  • Non-standard payload conventions that only the platform's tools can decode.

Each of these can be a good feature. The problem appears when your firmware depends on them without an abstraction.

Common Sources of MQTT Vendor Lock-In

Source Example pattern Why it locks you in Portable alternative
Reserved topics Platform shadow or event topics with a vendor prefix Firmware hard-codes paths only one service understands Your own hierarchy, e.g. site/area/line/device/telemetry
Device-to-cloud only models Fixed per-device telemetry and command topics Devices cannot subscribe to each other or to shared topics Standard publish/subscribe with wildcards
Proprietary auth Signed tokens generated by a vendor SDK Every device needs new credential logic to move Username/password or X.509 over standard TLS
Vendor SDKs Platform client libraries for shadows, jobs, provisioning Application code calls platform APIs, not MQTT Paho, MQTT.js, PubSubClient, ESP-MQTT
In-broker rules Routing logic in a platform rules language Business logic must be rewritten to move External subscribers, Node-RED or stream processing you own
Platform state services Shadow or twin documents State model tied to one API Retained messages on state topics

Platform features are not bad. AWS, Azure and other providers offer them because they save real work. The point is to make adopting them a conscious decision rather than an accident, and to keep them out of device firmware where changes are most expensive.

Seven Rules for Portable MQTT Systems

  1. Own your topic namespace. Design a hierarchy that describes your business, such as an ISA-95 style enterprise/site/area/line/cell/device. Avoid vendor prefixes in device topics.
  2. Use standard client libraries. Paho, MQTT.js, PubSubClient, AsyncMqttClient or ESP-MQTT work with any broker.
  3. Keep connection settings in configuration. Host, port, TLS settings, credentials and client ID should come from a config file, NVS storage or provisioning, never from constants scattered through code.
  4. Use standard authentication. Username and password over TLS, or client certificates, are understood by every serious broker.
  5. Represent state with retained messages. Reported and desired state on retained topics behaves the same everywhere.
  6. Put integration logic outside the broker. A Node-RED flow, Telegraf agent or small subscriber service connects to the broker as a normal client and can follow you to any provider.
  7. Document your payload contracts. JSON schemas or Sparkplug B are both open; undocumented binary formats are lock-in of your own making.

Example: Configuration-Driven Connections

The simplest anti-lock-in technique is to keep broker details in a single config file. Here is a YAML file and a Python loader using paho-mqtt 2.x:

# broker.yaml - change this file, not your code, to switch providers
host: broker.connectmq.com
port: 8883
tls: true
username: YOUR_USERNAME
password: YOUR_PASSWORD
client_id: YOUR_CLIENT_ID
topic_root: acme/plant1/packaging/line2
# pip install paho-mqtt pyyaml
import json
import ssl
import time
import yaml
import paho.mqtt.client as mqtt

with open("broker.yaml", encoding="utf-8") as f:
    cfg = yaml.safe_load(f)

root = cfg["topic_root"]


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe(f"{root}/+/cmd", qos=1)


def on_message(client, userdata, msg):
    print("Command:", msg.topic, msg.payload.decode())


client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=cfg["client_id"],
    protocol=mqtt.MQTTv5,
)
if cfg.get("username"):
    client.username_pw_set(cfg["username"], cfg.get("password"))
if cfg.get("tls"):
    client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
client.on_message = on_message
client.connect(cfg["host"], cfg["port"], keepalive=60)
client.loop_start()

try:
    while True:
        reading = {"speed": 118.5, "ts": int(time.time())}
        client.publish(f"{root}/filler1/telemetry", json.dumps(reading), qos=1)
        client.publish(f"{root}/filler1/state/reported",
                       json.dumps({"mode": "running"}), qos=1, retain=True)
        time.sleep(10)
except KeyboardInterrupt:
    client.loop_stop()
    client.disconnect()

Nothing in the application logic knows which provider it is talking to. Changing brokers means editing five lines of YAML.

Lock-In Beyond the Device

Firmware is the most expensive place to be locked in, because changing it means touching every device in the field. It is not the only place, though.

Back-end consumers often depend on a provider's delivery mechanism, for example a proprietary event stream that only exists on one platform. If your historian, dashboards and alerting subscribe to the broker over MQTT instead, they move with you.

Operational knowledge is a quieter form of lock-in. Runbooks, alert thresholds and debugging habits grow around one console. Writing down which signals you watch, such as connection counts, message rates and specific topics, makes them easy to recreate elsewhere.

Commercial terms matter too. Long commitments, data egress costs and plan structures can make moving expensive even when the technology is portable. Review them with the same care as the technical design.

A managed broker such as ConnectMQ handles the infrastructure for you, while devices, consumers and dashboards all talk plain MQTT. That combination gives you the convenience of a service without making the service hard to leave.

Run a Portability Test Before You Need One

The best proof of portability is to actually run your stack against a second broker. A free private broker or the public MQTT test broker is enough:

# Point a subscriber at the second broker and replay your test suite
mosquitto_sub -h broker.connectmq.com -p 1883 -i porttest-5d1e \
  -t "connectmq/demo/5d1e/#" -v

Set topic_root to connectmq/demo/5d1e in a copy of broker.yaml, disable TLS and credentials for the public broker, and run the same program. If it works unchanged, your device code is portable. If it breaks, the failures point exactly at the lock-in you need to remove.

Being Honest About Every Provider, Including Us

No managed service is perfectly neutral. ConnectMQ is a standards-based MQTT 3.1.1/5.0 broker, and your devices connect with ordinary clients and username/password authentication. Some portal conveniences, such as Sparkplug B republishing into topics under the connectmq/ prefix, threshold alerts or the ISA-95 devices view, are specific to this service. Use them freely for operations and dashboards, but keep device firmware publishing to your own topic tree so you could move it elsewhere. The same advice applies to any other provider's extras.

An Exit Plan Checklist

Write this down once and review it yearly:

  • Where are broker host, port and credentials stored for each device type?
  • Can devices receive new connection settings remotely?
  • Which features would need to be rebuilt elsewhere (rules, alerts, dashboards)?
  • Which topics or payload formats are provider-specific?
  • How would you run old and new brokers in parallel during migration, for example with a bridge?

The self-hosted vs managed MQTT broker comparison and the IoT platform vs MQTT broker article help decide which layer you actually want to outsource.

Build on a Standards-Based Broker

If portability matters to you, start on a broker that stays out of your firmware's way. Create a free Serverless broker with no credit card, run the YAML-driven client above, and keep full control of your topic design. For the wider picture, read the cloud MQTT broker guide, learn what an MQTT broker does, or visit ConnectMQ.

Frequently Asked Questions

Can you get locked in with an open protocol like MQTT?

Yes. The protocol is portable, but reserved topics, proprietary authentication, vendor SDKs and in-broker logic can tie devices to one provider.

Is using a platform's rules engine always lock-in?

It creates dependency, but that can be an acceptable trade-off. Keep such logic out of device firmware so moving later only affects the back end.

What is the quickest way to check if my devices are portable?

Point a test device at a second standards-based broker by changing only its configuration. Anything that breaks reveals a dependency.

Does Sparkplug B cause vendor lock-in?

No. Sparkplug B is an open Eclipse specification supported by many tools and brokers, so it is a portable choice for industrial payloads.

Related articles

BYOC MQTT Broker: Bring Your Own Cloud Explained

A BYOC MQTT broker runs in your cloud account but is operated by a provider. Learn how the model works, the responsibility split, and how to prepare your account for it.

7 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.