MQTT brokers can handle millions of concurrent connections, but a production system needs careful architecture to achieve high throughput.

Here’s a look at an MQTT production architecture designed for high throughput, using EMQX as an example:

+---------------------+       +---------------------+       +---------------------+
|     Load Balancer   | ----> |   EMQX Cluster Node 1 | ----> |    Database/Cache   |
+---------------------+       +---------------------+       +---------------------+
                                       ^
                                       |
+---------------------+       +---------------------+
|     Load Balancer   | ----> |   EMQX Cluster Node 2 | ----> |    Database/Cache   |
+---------------------+       +---------------------+       +---------------------+
                                       ^
                                       |
+---------------------+       +---------------------+
|     Load Balancer   | ----> |   EMQX Cluster Node 3 | ----> |    Database/Cache   |
+---------------------+       +---------------------+       +---------------------+

The Problem: A single MQTT broker can become a bottleneck under heavy load. As the number of concurrent connections, messages published, and messages delivered increases, the broker’s CPU, memory, and network I/O can be exhausted. This leads to dropped connections, delayed messages, and an overall unreliable system.

How it Works Internally:

  1. Distributed Architecture: High throughput is achieved by distributing the load across multiple EMQX nodes. Each node is a full-fledged broker, capable of handling a subset of the total connections and message traffic.
  2. Clustering: EMQX nodes form a cluster. This allows them to share connection state, topic subscriptions, and route messages efficiently. When a client connects to any node, that node becomes its "home" node. If a message is published to a topic that other clients subscribed to on different nodes, the home node routes the message to the appropriate node in the cluster. This inter-node communication is crucial for scalability.
  3. Load Balancing: External load balancers (like HAProxy, Nginx, or cloud provider LBs) distribute incoming client connections across the EMQX cluster nodes. This ensures no single node is overwhelmed by new connections.
  4. Data Persistence & State Management: While EMQX itself is primarily an in-memory broker for speed, production systems often integrate with external databases (like PostgreSQL, Cassandra, Redis) for:
    • Session Persistence: Storing client session state (subscriptions, QoS levels) so clients can reconnect seamlessly.
    • Message Persistence (for QoS 1 & 2): Storing messages that need to be delivered reliably.
    • Authentication/Authorization: Storing user credentials and access control lists.
  5. Publish/Subscribe Routing:
    • When a client publishes a message, its home node receives it.
    • EMQX checks its internal subscription tables to see which clients (potentially on other nodes) are subscribed to this topic.
    • The message is forwarded to the relevant nodes for delivery.
    • If persistence is enabled for the message, it’s also sent to the backend database.

Levers You Control:

  • Number of Nodes: More nodes mean more capacity. Scale horizontally by adding more EMQX instances.
  • Node Resources: The CPU, RAM, and network bandwidth of each EMQX node directly impact its individual capacity. Larger instances can handle more connections and higher message rates.
  • Load Balancer Configuration: How you distribute connections (e.g., round-robin, least connections) and handle health checks is critical.
  • Backend Database Performance: If your database becomes a bottleneck for session management or message persistence, it will limit your overall throughput.
  • MQTT QoS Levels: Higher QoS levels (QoS 1 and 2) require more acknowledgments and potentially persistence, increasing the load on the broker.
  • Topic Structure: Deeply nested topics can sometimes impact routing efficiency, though EMQX is generally very good at handling this.
  • Client Behavior: The number of clients, their connection patterns (e.g., bursty publishing), and their subscription patterns all influence system load.

The most surprising truth about scaling MQTT is that the inter-node communication within the cluster often becomes the limiting factor before individual node capacity is fully reached, especially for very high message volumes. This is because every message published to a topic with subscribers on other nodes requires network hops between EMQX instances. Optimizing this internal routing and ensuring high-speed, low-latency network connectivity between cluster nodes is paramount.

The next step in scaling is often optimizing the integration with your backend systems for authentication, authorization, and persistent storage.

Want structured learning?

Take the full Mqtt course →