Managed MQTT Cloud

MQTT Prototype to Production: A Step-by-Step Migration Path

A prototype on a public broker proves the idea. This guide takes it through credentials, TLS, topic namespacing, presence tracking and monitoring so it is ready for real users.

MQTT prototype to production illustration showing a breadboard sensor moving through security, topics and monitoring stages to a cloud broker
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

Taking an MQTT prototype to production is mostly about closing the gaps a demo can ignore: who can connect, who can read the data, how topics are organized and how you find out when something breaks. This guide walks a typical hobby project from the public test broker to a private, TLS-protected broker with a clean namespace and basic monitoring, in the order that causes the least rework.

The Starting Point: A Working Prototype

Most MQTT projects begin the same way. A sensor or an ESP32 publishes JSON to a public MQTT test broker, a laptop runs mosquitto_sub or a Node-RED flow, and the data shows up. A typical prototype looks like this:

mosquitto_pub -h broker.connectmq.com -p 1883 -i proto-dev-x9f3 \
  -t "connectmq/demo/x9f3/temp" -m '{"c":22.1}'

That is a perfectly good way to start. It is also not production, for five reasons:

  1. No authentication. Anyone can connect; the public area of broker.connectmq.com is readable by everyone.
  2. No encryption. Port 1883 sends credentials and payloads in clear text.
  3. Ad hoc topics. The topic tree grew organically and will not survive more than a handful of devices.
  4. No presence. You cannot tell an offline device from a quiet one.
  5. No visibility. When data stops, you find out because a chart looks flat.

The steps below close each gap in turn.

Step 1: Move to Private Credentials

Create an account at app.connectmq.com, pick a plan, create a broker and copy the generated username, password and client ID. The free Serverless plan is enough for a pilot of up to 25 connections; the paid Serverless plan raises that to 1,000 and adds QoS 2, 1 MB messages and shared subscriptions.

Two rules make the rest of the migration painless:

  • One credential set per device or service. Client IDs are bound to issued credentials, so sharing one set between two devices makes them disconnect each other.
  • Keep credentials out of source control. Load them from environment variables, a secrets file excluded from git, or a provisioning step at the factory.
# .env (never commit this file)
MQTT_HOST=broker.connectmq.com
MQTT_PORT=8883
MQTT_USERNAME=YOUR_USERNAME
MQTT_PASSWORD=YOUR_PASSWORD
MQTT_CLIENT_ID=YOUR_CLIENT_ID

Step 2: Turn On TLS Everywhere

Production traffic should use TLS on port 8883 for devices and Secure WebSocket on port 8084 with path /mqtt for browsers. ConnectMQ uses a Let's Encrypt certificate, so most operating systems and language runtimes already trust it. On microcontrollers you typically embed the ISRG Root X1 certificate; our ESP32 MQTT SSL guide shows the details.

Here is the prototype publisher rewritten for production in Python with paho-mqtt 2.x. It reads credentials from the environment, connects over TLS with MQTT 5, sets a Last Will so the broker can announce unexpected disconnects, and publishes a retained online status.

import json
import os
import time

import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes

HOST = os.environ["MQTT_HOST"]
PORT = int(os.environ.get("MQTT_PORT", "8883"))
CLIENT_ID = os.environ["MQTT_CLIENT_ID"]
BASE = "acme/site1/greenhouse/zone2/sensor-01"   # production namespace

def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print("connect failed:", reason_code)
        return
    print("connected")
    client.publish(f"{BASE}/status", "online", qos=1, retain=True)

def on_disconnect(client, userdata, flags, reason_code, properties):
    print("disconnected:", reason_code)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=CLIENT_ID, protocol=mqtt.MQTTv5)
client.username_pw_set(os.environ["MQTT_USERNAME"], os.environ["MQTT_PASSWORD"])
client.tls_set()
client.will_set(f"{BASE}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
client.on_connect = on_connect
client.on_disconnect = on_disconnect

connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 3600   # keep the session for an hour offline

client.connect(HOST, PORT, keepalive=60, properties=connect_props)
client.loop_start()

try:
    while True:
        reading = {"ts": int(time.time()), "temp_c": 22.1, "rh": 61}
        client.publish(f"{BASE}/telemetry", json.dumps(reading), qos=1)
        time.sleep(30)
except KeyboardInterrupt:
    client.publish(f"{BASE}/status", "offline", qos=1, retain=True).wait_for_publish()
    client.disconnect()
    client.loop_stop()

Notice how little changed compared with the prototype: hostname, port, credentials, TLS and a few properties. That is the point of using standard MQTT end to end.

Step 3: Design a Production Topic Namespace

A prototype topic like connectmq/demo/x9f3/temp works for one sensor. A production namespace has to survive new sites, new device types and new consumers without renaming anything. A good structure goes from general to specific and separates data from commands and status.

Level Example Purpose
Organization or tenant acme Isolates customers or business units
Site site1 Physical location
Area greenhouse Building, line or room
Unit zone2 Logical group of devices
Device sensor-01 Stable device identifier
Message class telemetry, status, cmd, cmd/ack What the message is

Practical rules that save pain later:

  • Keep levels lowercase, no spaces, no leading slash.
  • Put the device ID in the topic, not only in the payload, so subscribers can filter with wildcards.
  • Use a separate cmd branch for commands so devices subscribe narrowly.
  • Make status topics retained so late subscribers see the current state immediately.
  • Keep depth reasonable; the public broker allows 8 levels, which is a sensible budget anywhere.

If your project is industrial, consider aligning with ISA-95 levels from the start. ConnectMQ's devices view groups clients by ISA-95 levels when your topics follow that pattern. Our smart home MQTT topic structure guide covers residential projects.

Step 4: Track Device Presence

Retained online and offline status messages with a Last Will, as in the code above, give every subscriber a reliable view of which devices are connected. You can also watch broker-side state through $SYS/broker/connection/{clientId}/state, which is useful for a backend service that needs to know when a specific client drops.

mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_CLIENT_ID -V mqttv5 \
  -t 'acme/site1/+/+/+/status' -v

Step 5: Add Monitoring and Alerts

Production means someone finds out about problems before users do. Start simple:

  • Use the portal dashboard and live topic explorer to confirm data is flowing after each deployment.
  • Create threshold alert rules for values that matter, such as a temperature out of range, and review the alerts log.
  • Log MQTT 5 reason codes on every client so quota and authorization problems are diagnosable.
  • If you need long-term storage or custom notifications, run your own subscriber, for example a Python service, Telegraf or Node-RED, that connects to the broker as a normal MQTT client and writes to your database or messaging tool.

For a deeper list, read our MQTT broker monitoring guide.

The Production Readiness Checklist

Before you ship, confirm each item:

  1. Every device and service has its own credentials and client ID.
  2. All connections use TLS (8883) or Secure WebSocket (8084).
  3. No credentials live in firmware source control.
  4. The topic namespace is documented and starts with an organization or tenant level.
  5. Devices publish retained status with a Last Will.
  6. Reconnect logic uses exponential backoff with jitter.
  7. Payloads stay well under the plan's message size limit.
  8. Commands use at least QoS 1 and are safe to receive twice.
  9. You have a plan for firmware updates that rotate credentials.
  10. Alerts reach a human when key values or device presence change.

When the list is done, the MQTT production checklist and MQTT security best practices go further on hardening.

Choosing the Right Plan for Production

Start with the smallest plan that covers your connection count with headroom. Move to paid Serverless when you need more than 25 connections, QoS 2, larger messages or shared subscriptions for backend consumers. Choose Dedicated when you want an isolated cluster, BYOC when the broker must run in your own cloud account, and Self Managed Enterprise when you need to run it yourself. The cloud MQTT broker guide compares these hosting models in more depth.

Take Your Prototype to Production with ConnectMQ

ConnectMQ gives you private credentials, TLS, MQTT 5 and a portal with a live topic explorer and alert rules, on the same standard MQTT your prototype already speaks. Sign up at app.connectmq.com, create a broker on the free Serverless plan with no credit card, and point your prototype at it in minutes. If you would rather not run any infrastructure yourself, a managed MQTT broker is the shortest path.

Frequently Asked Questions

Can I keep using the public broker in production?

No. The public area of broker.connectmq.com is readable by everyone and has tight per-client limits, so it is meant for testing only. Production data belongs on a private broker with credentials and TLS.

Do I need to change my device code to move to production?

Usually only the connection settings change: hostname, port 8883, credentials and TLS. Topic names change if you adopt a new namespace, which is worth doing before you scale.

How should I handle credentials on many devices?

Issue one credential set per device, load it during provisioning rather than compiling it into shared firmware, and keep a record so you can revoke a single device without touching the others.

Which plan should a small pilot use?

A pilot with up to 25 concurrent connections fits the free Serverless plan. Move to paid Serverless when you need more connections, QoS 2 or larger messages.

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.