IoT 2026 MQTT Broker Self-Hosting Tutorial: Mosquitto Server Configuration and Optimization
Friends doing IoT development definitely can’t avoid the MQTT protocol. Today we’ll talk about how to self-host a reliable MQTT broker server, using the open-source solution Eclipse Mosquitto.
Why self-host? Public MQTT servers are convenient, but data security isn’t guaranteed, and connection stability depends on their mood. If you build it yourself, you have complete control over the data, and can customize and optimize according to your needs.
What Do You Need?
| Item | Model/Spec | Price |
|---|---|---|
| Server | Raspberry Pi 4B / Cloud server | ¥350-500 |
| Or | Old laptop/desktop | ¥0 (reuse) |
| Storage | 16GB SD card / SSD | ¥30-200 |
| Network | Wired network preferred | ¥0 |
| Domain | Optional (for external access) | ¥50/year |
| Total | ¥80-750 |
I’m using an idle Raspberry Pi 4B at home, running 24/7 with only about 5W power consumption, less than 30 yuan in electricity per year, great deal!
Step 1: Install Mosquitto
Ubuntu/Debian System
# Update package sources
sudo apt-get update
# Install Mosquitto and client tools
sudo apt-get install -y mosquitto mosquitto-clients
# Check service status
systemctl status mosquitto
Fedora/CentOS System
# Enable EPEL repository
sudo dnf install -y epel-release
# Install Mosquitto
sudo dnf install -y mosquitto mosquitto-clients
# Start service
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
Docker Method (Recommended)
If you’re already familiar with Docker, this method is the cleanest:
docker run -d \
--name mosquitto \
--restart always \
-p 1883:1883 \
-p 9001:9001 \
-v /opt/mosquitto/config:/mosquitto/config \
-v /opt/mosquitto/data:/mosquitto/data \
-v /opt/mosquitto/log:/mosquitto/log \
eclipse-mosquitto:latest
Notes: ⚠️ By default after installation, Mosquitto allows anonymous connections. You must configure authentication in production environments!
Step 2: Basic Configuration
Configuration file location: /etc/mosquitto/mosquitto.conf
Minimum Security Configuration
# Backup original config
sudo cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.bak
# Create config file
sudo nano /etc/mosquitto/mosquitto.conf
Fill in the following content:
# Listen ports
listener 1883
listener 9001
protocol websockets
# Disable anonymous connections
allow_anonymous false
# Password file path
password_file /etc/mosquitto/passwd
# Persistence settings
persistence true
persistence_location /var/lib/mosquitto/
# Log configuration
log_dest file /var/log/mosquitto/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information
# Connection limits
max_connections 1000
max_queued_messages 100
Create User Passwords
# Create password file (use -c parameter for first user)
sudo mosquitto_passwd -c /etc/mosquitto/passwd admin
# Add more users (don't use -c)
sudo mosquitto_passwd /etc/mosquitto/passwd device001
sudo mosquitto_passwd /etc/mosquitto/passwd device002
# Set file permissions
sudo chmod 600 /etc/mosquitto/passwd
sudo chown mosquitto:mosquitto /etc/mosquitto/passwd
How it works: Mosquitto uses PBKDF2-SHA256 algorithm to hash passwords, security is sufficient. It’s recommended to use independent accounts for each device, convenient for permission management and troubleshooting.
Step 3: Configure TLS Encryption (Optional but Recommended)
If devices access from external network, TLS encryption is strongly recommended.
Use Let’s Encrypt Free Certificate
# Install Certbot
sudo apt-get install -y certbot
# Get certificate (requires domain name)
sudo certbot certonly --standalone -d mqtt.yourdomain.com
# Certificate location
# /etc/letsencrypt/live/mqtt.yourdomain.com/fullchain.pem
# /etc/letsencrypt/live/mqtt.yourdomain.com/privkey.pem
Modify Mosquitto Configuration
# TLS listen port
listener 8883
protocol mqtt
# Certificate configuration
cafile /etc/letsencrypt/live/mqtt.yourdomain.com/chain.pem
certfile /etc/letsencrypt/live/mqtt.yourdomain.com/fullchain.pem
keyfile /etc/letsencrypt/live/mqtt.yourdomain.com/privkey.pem
# Force TLS
require_certificate false
Restart service:
sudo systemctl restart mosquitto
Step 4: Test Connection
Command Line Test
# Terminal 1: Subscribe to topic
mosquitto_sub -h localhost -p 1883 -u admin -P yourpassword -t "test/topic" -v
# Terminal 2: Publish message
mosquitto_pub -h localhost -p 1883 -u admin -P yourpassword -t "test/topic" -m "Hello MQTT!"
If you see terminal 1 receive the message, configuration is successful!
Python Client Test
import paho.mqtt.client as mqtt
import time
# Callback functions
def on_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
client.subscribe("test/topic")
def on_message(client, userdata, msg):
print(f"{msg.topic}: {msg.payload.decode()}")
# Create client
client = mqtt.Client()
client.username_pw_set("admin", "yourpassword")
client.on_connect = on_connect
client.on_message = on_message
# Connect
client.connect("localhost", 1883, 60)
client.loop_start()
# Publish messages
for i in range(5):
client.publish("test/topic", f"Message {i}")
time.sleep(1)
time.sleep(3)
client.loop_stop()
client.disconnect()
Step 5: Performance Optimization
Adjust System Limits
# Edit system limits
sudo nano /etc/security/limits.conf
# Add the following content
mosquitto soft nofile 65536
mosquitto hard nofile 65536
Mosquitto Advanced Configuration
# Message queue optimization
max_queued_messages 10000
max_inflight_messages 20
retry_interval 20
# Heartbeat interval (seconds)
keepalive_interval 60
# Auto save interval (seconds)
autosave_interval 1800
# Client timeout
timeout_idle 0
Monitor Connection Status
# View active client count
mosquitto_sub -t '$SYS/broker/clients/connected' -h localhost
# View message statistics
mosquitto_sub -t '$SYS/broker/messages/#' -h localhost
# View load status
mosquitto_sub -t '$SYS/broker/load/#' -h localhost
Common Problem Troubleshooting
Problem 1: Connection refused
-
Cause: Firewall blocking port 1883
-
Solution:
sudo ufw allow 1883/tcp
sudo ufw allow 8883/tcp
sudo systemctl restart mosquitto
Problem 2: Authentication failed (Not authorized)
-
Cause: Wrong username/password or incorrect password file permissions
-
Solution:
# Check password file permissions
ls -la /etc/mosquitto/passwd
# Should be -rw------- mosquitto mosquitto
# Reset password
sudo mosquitto_passwd /etc/mosquitto/passwd admin
Problem 3: TLS connection failed
-
Cause: Certificate path error or permission issue
-
Solution:
# Check certificate files
ls -la /etc/letsencrypt/live/yourdomain/
# Mosquitto needs read permissions
sudo chmod 644 /etc/letsencrypt/live/yourdomain/*.pem
sudo chown mosquitto:mosquitto /etc/letsencrypt/live/yourdomain/*.pem
Problem 4: Message loss
-
Cause: QoS level set improperly or client disconnected abnormally
-
Solution:
Use QoS 1 or QoS 2 for critical messages
-
Enable persistence (persistence true)
-
Client sets clean_session=false
Problem 5: Performance degradation due to too many connections
-
Cause: Default configuration not suitable for high concurrency
-
Solution:
Adjust max_connections
-
Increase system file descriptor limit
-
Consider cluster deployment (multiple Mosquitto instances)
Summary
Self-hosting an MQTT broker server isn’t difficult, Mosquitto is lightweight and stable. Key points:
-
Enable user authentication (
allow_anonymous false), prohibit anonymous connections -
Assign independent accounts for each device, convenient for permission management and troubleshooting
-
Must enable TLS encryption for external access, prevent data eavesdropping
-
Reasonably set
max_connectionsand file descriptor limits, handle high concurrency scenarios
For small-scale IoT projects, a single Mosquitto can support thousands of devices. For larger scale, you can consider enterprise-level solutions like EMQX, or Mosquitto cluster deployment.
Hope this blog article is helpful to you!
Related resources: