EMQX Cheat Sheet
Overview
EMQX is a highly scalable, distributed MQTT messaging broker designed for IoT, M2M, and mobile applications. It supports MQTT 5.0, 3.1.1, and 3.1 protocols along with MQTT-SN, CoAP, LwM2M, and WebSocket transports. EMQX can handle millions of concurrent connections on a single cluster with low latency and high throughput.
EMQX features a built-in rule engine for real-time data processing, rich authentication and authorization mechanisms, data bridges to databases and cloud services, and a comprehensive dashboard for monitoring. It is available as open-source edition and enterprise edition with additional features like data persistence and Kafka integration.
Installation
Docker
docker run -d --name emqx \
-p 1883:1883 \
-p 8083:8083 \
-p 8084:8084 \
-p 8883:8883 \
-p 18083:18083 \
emqx/emqx:5.6.0
Linux Package
# Ubuntu/Debian
wget https://www.emqx.com/en/downloads/broker/5.6.0/emqx-5.6.0-ubuntu22.04-amd64.deb
sudo dpkg -i emqx-5.6.0-ubuntu22.04-amd64.deb
# Start EMQX
sudo systemctl start emqx
sudo systemctl enable emqx
Docker Compose Cluster
version: '3'
services:
emqx1:
image: emqx/emqx:5.6.0
environment:
EMQX_NODE_NAME: emqx@node1.emqx.io
EMQX_CLUSTER__DISCOVERY_STRATEGY: static
EMQX_CLUSTER__STATIC__SEEDS: '[emqx@node1.emqx.io,emqx@node2.emqx.io]'
ports:
- "1883:1883"
- "18083:18083"
emqx2:
image: emqx/emqx:5.6.0
environment:
EMQX_NODE_NAME: emqx@node2.emqx.io
EMQX_CLUSTER__DISCOVERY_STRATEGY: static
EMQX_CLUSTER__STATIC__SEEDS: '[emqx@node1.emqx.io,emqx@node2.emqx.io]'
Dashboard Access
# Default URL: http://localhost:18083
# Default credentials: admin / public
Core CLI Commands
| Command | Description |
|---|---|
emqx start | Start EMQX node |
emqx stop | Stop EMQX node |
emqx restart | Restart EMQX node |
emqx status | Check node status |
emqx console | Start in foreground |
emqx ctl cluster status | Show cluster status |
emqx ctl cluster join emqx@node2 | Join a cluster |
emqx ctl cluster leave | Leave the cluster |
emqx ctl clients list | List connected clients |
emqx ctl topics list | List subscribed topics |
emqx ctl subscriptions list | List all subscriptions |
REST API
# Base URL: http://localhost:18083/api/v5
# Auth: Basic auth with API key
# List clients
curl -s -u admin:public \
http://localhost:18083/api/v5/clients | jq .
# Get specific client
curl -s -u admin:public \
http://localhost:18083/api/v5/clients/my-client-id
# Disconnect a client
curl -X DELETE -u admin:public \
http://localhost:18083/api/v5/clients/my-client-id
# Publish a message via API
curl -X POST -u admin:public \
-H "Content-Type: application/json" \
http://localhost:18083/api/v5/publish \
-d '{"topic":"test/api","payload":"Hello","qos":1,"retain":false}'
# List topics
curl -s -u admin:public \
http://localhost:18083/api/v5/topics | jq .
# Get broker stats
curl -s -u admin:public \
http://localhost:18083/api/v5/stats | jq .
Configuration
Main Config (etc/emqx.conf)
# Node settings
node {
name = "emqx@127.0.0.1"
cookie = "emqxsecretcookie"
data_dir = "data"
}
# MQTT listener
listeners.tcp.default {
bind = "0.0.0.0:1883"
max_connections = 1024000
acceptors = 16
}
# WebSocket listener
listeners.ws.default {
bind = "0.0.0.0:8083"
max_connections = 1024000
}
# SSL/TLS listener
listeners.ssl.default {
bind = "0.0.0.0:8883"
ssl_options {
certfile = "etc/certs/cert.pem"
keyfile = "etc/certs/key.pem"
cacertfile = "etc/certs/cacert.pem"
}
}
# MQTT protocol settings
mqtt {
max_packet_size = 1MB
max_clientid_len = 65535
max_topic_levels = 128
max_qos_allowed = 2
max_topic_alias = 65535
retain_available = true
shared_subscription = true
}
Authentication Configuration
# Password-based authentication
authentication = [
{
mechanism = password_based
backend = built_in_database
password_hash_algorithm {
name = sha256
salt_position = suffix
}
}
]
# JWT authentication
authentication = [
{
mechanism = jwt
from = password
algorithm = hmac-based
secret = "my-jwt-secret"
verify_claims {
username = "${username}"
}
}
]
Authorization (ACL)
authorization {
sources = [
{
type = built_in_database
enable = true
},
{
type = file
enable = true
path = "etc/acl.conf"
}
]
no_match = deny
deny_action = disconnect
}
Rule Engine
# Create a rule via API
curl -X POST -u admin:public \
-H "Content-Type: application/json" \
http://localhost:18083/api/v5/rules \
-d '{
"id": "temperature_alert",
"sql": "SELECT payload.temp as temperature, clientid FROM \"sensor/+/temperature\" WHERE payload.temp > 40",
"actions": [
{
"function": "republish",
"args": {
"topic": "alerts/high_temp/${clientid}",
"payload": "{\"alert\": \"High temperature: ${temperature}\"}"
}
}
]
}'
# List rules
curl -s -u admin:public \
http://localhost:18083/api/v5/rules | jq .
Advanced Usage
Data Bridges
# Create a webhook bridge
curl -X POST -u admin:public \
-H "Content-Type: application/json" \
http://localhost:18083/api/v5/bridges \
-d '{
"type": "webhook",
"name": "my_webhook",
"connector": {
"url": "http://myapp.example.com/webhook",
"method": "post",
"headers": {"Content-Type": "application/json"}
},
"enable": true
}'
Cluster Configuration
# Static cluster discovery
cluster {
name = emqxcl
discovery_strategy = static
static {
seeds = ["emqx@node1.example.com", "emqx@node2.example.com"]
}
}
# DNS-based discovery
cluster {
name = emqxcl
discovery_strategy = dns
dns {
name = "emqx.service.consul"
record_type = srv
}
}
Monitoring
# Prometheus metrics endpoint
curl http://localhost:18083/api/v5/prometheus/stats
# Key metrics
# emqx_connections_count — current connections
# emqx_live_connections_count — active connections
# emqx_messages_received — messages received
# emqx_messages_sent — messages sent
# emqx_topics_count — number of topics
# emqx_subscriptions_count — number of subscriptions
# emqx_bytes_received — bytes received
# emqx_bytes_sent — bytes sent
Troubleshooting
| Issue | Solution |
|---|---|
| Node won’t join cluster | Verify same cookie; check DNS resolution between nodes |
| Client connection rejected | Check authentication config; verify listener is bound correctly |
| High memory usage | Tune max_connections; check for session buildup from disconnected clients |
| Messages not delivered | Verify topic matches subscription; check QoS levels and ACL rules |
| Dashboard inaccessible | Ensure port 18083 is open; check dashboard listener config |
| Rule engine not firing | Verify SQL syntax; test topic pattern matching; check rule status |
| TLS handshake failure | Verify certificate chain; check TLS version compatibility |
| Cluster split-brain | Implement auto-heal config; monitor network partition detection |