Skip to content
Go back

MQTT Broker Choices: Mosquitto vs EMQX

By SumGuy 8 min read
MQTT Broker Choices: Mosquitto vs EMQX

The Broker Choice Nobody Wants to Think About

You’ve got a dozen IoT devices around your home. Your Home Assistant box is polling them. Your Frigate camera is dumping events. Your Tasmota switches are reporting state changes. And somewhere in that chaos, you need to pick an MQTT broker—the message bus that everything talks to.

The choice sounds boring. It’s not. Pick the wrong one, and you’re either throwing away CPU cycles on unnecessary bloat or scrambling to add features you should’ve planned for. Pick right, and your home stack hums along invisible.

Let me cut through it: Mosquitto is the default choice for 99% of home labs. EMQX is there if you’ve outgrown Mosquitto or you’re planning to outgrow it before you build it. This post is about knowing which one you actually need, not which one has the fancier name.


Mosquitto: The Lightweight Standard

Mosquitto is what you’re already running. It’s in every Docker repo, it’s one apt install away on Linux, and it just works. It’s been the home lab broker of choice since 2010.

Here’s what you get:

The trade-off? Mosquitto is single-node only. If your broker dies, everything stops until you restart it. For a home lab, that’s fine—you can survive an hour of downtime. Mosquitto also doesn’t scale horizontally. If you somehow end up with 10,000 clients (you won’t), Mosquitto maxes out around 1,000-2,000 depending on your hardware.

Here’s a typical Mosquitto Compose setup:

services:
mosquitto:
image: eclipse-mosquitto:latest
ports:
- "1883:1883"
- "8883:8883"
- "9001:9001"
volumes:
- ./config/mosquitto.conf:/mosquitto/config/mosquitto.conf
- ./data/mosquitto:/mosquitto/data
environment:
- TZ=UTC
restart: unless-stopped

And a basic config:

listener 1883
protocol mqtt
listener 8883
protocol mqtt
cafile /mosquitto/certs/ca.crt
certfile /mosquitto/certs/server.crt
keyfile /mosquitto/certs/server.key
listener 9001
protocol websockets
persistence true
persistence_location /mosquitto/data/

That’s it. Plug in some TLS certs, point your clients at your-homelab.local:1883, and you’re done. The whole thing runs on a 10-year-old laptop.


EMQX: The Feature-Laden Overachiever

EMQX is what Mosquitto wants to be when it grows up and gets a job at an IoT unicorn. It’s an Erlang-based broker built for scale, clustering, enterprise auth, and features Mosquitto doesn’t even know exist.

What you gain:

The downside? EMQX is 500+ MB on disk, runs 100+ MB RAM even idle, and requires actual operational overhead. Clustering means you need to think about networking, consensus, failover. If something breaks, you’re Googling Erlang error messages at midnight.

Here’s EMQX in Compose:

services:
emqx:
image: emqx/emqx:latest
ports:
- "1883:1883"
- "8883:8883"
- "9001:9001"
- "18083:18083"
environment:
- EMQX_NODE_NAME=emqx@emqx
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_AUTH__USER=admin
- EMQX_AUTH__PASSWORD=your-password-here
volumes:
- ./data/emqx:/opt/emqx/data
restart: unless-stopped
healthcheck:
test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"]
interval: 30s
timeout: 10s
retries: 3

Three nodes clustered together:

services:
emqx1:
image: emqx/emqx:latest
environment:
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
ports:
- "1883:1883"
volumes:
- ./data/emqx1:/opt/emqx/data
networks:
- mqtt
emqx2:
image: emqx/emqx:latest
environment:
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
ports:
- "1883:1883"
volumes:
- ./data/emqx2:/opt/emqx/data
networks:
- mqtt
emqx3:
image: emqx/emqx:latest
environment:
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
ports:
- "1883:1883"
volumes:
- ./data/emqx3:/opt/emqx/data
networks:
- mqtt
networks:
mqtt:
driver: bridge

Now you need to manage three stateful services, worry about clock skew, debug Erlang clustering quirks, and remember to upgrade all three at once. Fun!


Side-by-Side Comparison

FeatureMosquittoEMQX
Memory (idle)10-30 MB100-150 MB
Single-node setup5 minutes10 minutes
ClusteringNoYes (3+ nodes)
Max concurrent clients~2,000Millions
TLS/SSLYesYes
AuthenticationPassword file, basic ACLsHTTP hooks, JWT, SQL, LDAP, file, HTTP
PersistenceYesYes
WebSocketsYesYes
Message routingBasic bridgingRule engine (transform, filter, route)
MonitoringNone (use external tools)Built-in dashboard, Prometheus
Operational complexityMinimalModerate to high at scale
Learning curveHoursDays to weeks
Perfect forHome labs, small officesMulti-site deployments, high availability

When to Pick Mosquitto

Just use Mosquitto if:

This covers 98% of home labs. Seriously. If you stopped reading here and picked Mosquitto, you’d be making the right call.


When EMQX Makes Sense

Pick EMQX if:

Also: EMQX offers a cloud version if you want zero operational overhead. That’s not home lab territory—that’s “I’d rather pay money than debug Erlang” territory.


The Honest Take

You’re probably overthinking this. Start with Mosquitto. Run it in a container, point your devices at it, and move on. If it works for six months (it will), stop. Don’t add complexity preemptively.

The only reason to pick EMQX from day one is if you’re building something that’s explicitly multi-site or high-availability from the ground up. That’s rare in home labs. Most of us just want a message bus that doesn’t crash and let’s us avoid polling.

Here’s the real decision tree:

  1. Single home lab, <500 devices → Mosquitto. Done.
  2. Two locations that need to sync → Mosquitto with bridges.
  3. One location but you need HA clustering → EMQX, 3+ nodes.
  4. Complex auth or message routing → EMQX’s rule engine or HTTP hooks.
  5. Millions of connections → EMQX or HiveMQ (another option, not covered here).

Anything else is like hiring a forklift to move a couch. Technically it works, but your neighbors will have questions.


Migration Path (If You Change Your Mind)

Built Mosquitto and now you’re hitting limits? The migration is straightforward:

  1. Spin up EMQX alongside Mosquitto.
  2. Point new devices at EMQX.
  3. Move old devices one by one (subscribe to EMQX in Home Assistant, point the device, restart).
  4. Once all clients are on EMQX, kill Mosquitto.

MQTT clients don’t care which broker they’re talking to—they speak the same language. Use that to your advantage.


Final Word

Mosquitto is battle-tested, lightweight, and maintainable. EMQX is powerful, over-engineered, and worth the complexity if you actually need it. Pick Mosquitto first. Upgrade to EMQX later if you hit walls. That’s not settling—that’s respecting your own time.

Your 2 AM self will thank you for not running three clustered Erlang services when one lightweight C daemon would’ve done the job.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Next Post
ddrescue vs TestDisk vs PhotoRec

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts