Skip to content

Using MQTT

The MQTT Essentials series and MQTT Guide 2023 are great places to start in-depth learning. This document only outlines the most important concepts for implementation and serves as a reference for those familiar with MQTT.

Tip

Use MQTTX for a great MQTT testing and development client.

MQTT Brokers

Criteria for evaluation of MQTT brokers

  • Latency: How fast can the broker dispatch and deliver an MQTT message from one client to another?
  • Performance: How many QoS/0/1/2 MQTT messages per second can the broker route and deliver?
  • Reliability: Does the broker support MQTT message persistence and delivery without data loss?
  • Security: Does the broker support MQTT over WebSocket and SSL/TLS?

Less relevant items for simple use cases

  • Scalability: Can the broker scale horizontally to handle millions of concurrent MQTT connections?
  • Availability: Does the broker support highly available clustering for mission-critical applications?

Options

  • EMQX - Hugely scalable, overkill for simple use cases, advanced security features
  • NanoMQ - Fast, lightweight broker, multi-threaded,
  • Rumqttd - Written in rust, less community support and now widely used (not recommended)
  • Mosquitto - Single threaded, lightweight, widely used

Of the above brokers, the ones that stand out are EMQX, Mosquitto, and NanoMQ. Below is a head-to-head comparison of non-functional features.

EMQXMosquittoNanoMQ
ProtocolsMQTT 5.0/3.1.1 MQTT over QUICMQTT 5.0/3.1.1MQTT 5.0/3.1.1 MQTT over QUIC ZeroMQ & NanoMSG
ScalabilityExcellentModerateGood
AvailabilityExcellentModerateModerate
PerformanceExcellentGoodExcellent
LatencyExcellentGoodExcellent
ReliabilityHighHighHigh
SecurityExcellentExcellentGood
IntegrationsExcellentModerateModerate
CompatibilityGoodExcellentExcellent
Ease of UseGoodExcellentGood
Community SupportExcellentExcellentExcellent

Concepts

Quality of Service (QoS)

Defines the level of delivery guarantee for a specific message.

  • At most once (QoS 0)
  • At least once (QoS 1)
  • Exactly once (QoS 2)

Implementation & Design Tips

  1. Use bridging to connect MQTT brokers together and forward messages between them. This can give you a robust and modular framework for connectivity between many devices.

NanoMQ

NanoMQ Tip: If you enabled SQLite feature, NanoMQ will automatically flush cached messages into disk when network is disconnected. NanoMQ will resend cached messages once bridging connection is restored. But each cached message will be resent in a certain interval to avoid bandwidth exhaustion.

Bridging MQTT Brokers

Following the tutorial, the configuration docs, and the nanomq.conf configuration file in the Appendix.

You can validate comms between the broker and bridge with MQTTX test clients

  1. On MQTTBridge client, subscribe to fwd/#.
  2. On NanoMQTest client, publish a message on topic1. You should see a message arrive at MQTTBridge.
  3. On NanoMQTest client, subscribe to topic1.
  4. On MQTTBridge client, publish a message to cmd/topic1. You should see a message arrive at NanoMQTest.

Appendix

RESOURCES
nanomq.conf
toml
bridges.mqtt.name {
	## TCP URL format:  mqtt-tcp://host:port
	## TLS URL format:  tls+mqtt-tcp://host:port
	## QUIC URL format: mqtt-quic://host:port
	server = "mqtt-tcp://broker.emqx.io:1883"
	## MQTT protocol version(4 | 5)
	proto_ver = 4
	# username = admin
	# password = public
	clean_start = true
	keepalive = 60s
	## Uncomment if you need TLS
	## ssl {
	## 	keyfile = "/etc/certs/key.pem"
	## 	certfile = "/etc/certs/cert.pem"
	## 	cacertfile = "/etc/certs/cacert.pem"
	## }
	forwards = [
		{
			remote_topic = "fwd/topic1"
			local_topic = "topic1"
			qos = 1
		},
		{
			remote_topic = "fwd/topic2"
			local_topic = "topic2"
			qos = 2
		}
	]

	subscription = [
		{
			remote_topic = "cmd/topic1"
			local_topic = "topic1"
			qos = 1
		},
		{
			remote_topic = "cmd/topic2"
			local_topic = "topic2"
			qos = 2
		}
	]

	max_parallel_processes = 2 
	max_send_queue_len = 1024
	max_recv_queue_len = 1024
}
bridges.mqtt.name {
	## TCP URL format:  mqtt-tcp://host:port
	## TLS URL format:  tls+mqtt-tcp://host:port
	## QUIC URL format: mqtt-quic://host:port
	server = "mqtt-tcp://broker.emqx.io:1883"
	## MQTT protocol version(4 | 5)
	proto_ver = 4
	# username = admin
	# password = public
	clean_start = true
	keepalive = 60s
	## Uncomment if you need TLS
	## ssl {
	## 	keyfile = "/etc/certs/key.pem"
	## 	certfile = "/etc/certs/cert.pem"
	## 	cacertfile = "/etc/certs/cacert.pem"
	## }
	forwards = [
		{
			remote_topic = "fwd/topic1"
			local_topic = "topic1"
			qos = 1
		},
		{
			remote_topic = "fwd/topic2"
			local_topic = "topic2"
			qos = 2
		}
	]

	subscription = [
		{
			remote_topic = "cmd/topic1"
			local_topic = "topic1"
			qos = 1
		},
		{
			remote_topic = "cmd/topic2"
			local_topic = "topic2"
			qos = 2
		}
	]

	max_parallel_processes = 2 
	max_send_queue_len = 1024
	max_recv_queue_len = 1024
}