I was working on a smart home project last week when I hit a wall. My temperature sensors were sending data to a server, but the connections kept dropping. The battery life on my devices was terrible. I needed a better way for machines to talk to each other. That’s when I decided to build my own MQTT system. Let me show you what I learned.
MQTT is a messaging protocol built for the Internet of Things. It’s lightweight and efficient. Think of it as a postal system for your devices. Instead of constantly checking for mail, devices subscribe to topics they care about. When a message arrives for that topic, they get it immediately. This saves battery and bandwidth.
Why would you choose this over a regular HTTP API? Good question. HTTP is like having a conversation where you must ask a question and wait for an answer every single time. MQTT is more like a radio broadcast. One device publishes a message, and any device tuned to that station receives it. This is perfect for sensor data, chat applications, or real-time dashboards.
Let’s start by setting up a basic broker. The broker is the central server that manages all messages. In the MQTT world, it’s the post office. We’ll use a package called Aedes, which is a solid choice for Node.js.
First, create a new project and install the essentials.
npm init -y
npm install aedes mqtt
Now, let’s write a simple broker. This code creates a server that listens for MQTT connections.
const aedes = require('aedes')();
const server = require('net').createServer(aedes.handle);
const port = 1883;
server.listen(port, function () {
console.log(`Broker is ready on port ${port}`);
});
That’s it. You now have a working MQTT broker. Save this as broker.js and run it with node broker.js. But what can you do with it? You need clients to publish and subscribe.
Let’s create a client that publishes a message. Imagine it’s a weather sensor.
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost:1883');
client.on('connect', function () {
setInterval(() => {
const temperature = (20 + Math.random() * 10).toFixed(1);
client.publish('home/livingroom/temperature', temperature);
console.log(`Sent: ${temperature}°C`);
}, 5000);
});
This client connects to our broker and publishes a random temperature to the topic home/livingroom/temperature every five seconds. Topics are like addresses for messages. They are simple strings, often structured with slashes.
Now, we need something to listen for that data. A subscriber client could be a dashboard or a smart thermostat.
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost:1883');
client.on('connect', function () {
client.subscribe('home/+/temperature');
console.log('Subscribed to all temperature sensors');
});
client.on('message', function (topic, message) {
console.log(`Update on ${topic}: ${message.toString()}°C`);
});
Notice the + in the topic? That’s a single-level wildcard. This subscriber listens to home/livingroom/temperature, home/kitchen/temperature, or any other room. There’s also a # wildcard for multi-level matching. This flexible routing is a core strength of MQTT.
But our current setup has no security. Anyone can connect and publish anything. For a real project, we need authentication. How do we ensure only our devices can talk to the broker?
Aedes lets us add hooks to verify clients. Let’s add a simple username and password check.
const aedes = require('aedes')();
aedes.authenticate = function (client, username, password, callback) {
const authorized = (username === 'device_01' && password.toString() === 'secure_pass');
if (authorized) {
client.deviceId = username;
return callback(null, authorized);
}
const error = new Error('Authentication Failed');
return callback(error, false);
};
const server = require('net').createServer(aedes.handle);
server.listen(1883);
Now, clients must provide these credentials to connect. But storing passwords in code is a bad idea. In production, you would check against a database. You might also want to control what topics a client can publish or subscribe to. This is called authorization.
What happens if our broker restarts? All the messages in transit would be lost. For important data, we need persistence and guaranteed delivery. This is where Quality of Service, or QoS, comes in.
MQTT has three QoS levels. QoS 0 is “fire and forget.” The message is sent once. QoS 1 means “at least once.” The sender stores the message until it gets a confirmation. QoS 2 is “exactly once.” It’s the most reliable but also the slowest, using a four-step handshake.
Let’s publish a critical alert with QoS 1.
client.publish('system/alerts', 'Front door opened', { qos: 1 }, function (err) {
if (!err) {
console.log('Alert delivery confirmed.');
}
});
The callback runs when the broker confirms receipt. This ensures important messages aren’t lost. Subscribers can also request a QoS level, asking the broker to deliver messages with a certain guarantee.
As your system grows, a single broker might not handle all the connections. You might need to scale. One approach is broker clustering. Another is to use a bridge to connect multiple brokers together. This allows you to distribute the load.
You’ll also want to monitor your system. How many clients are connected? What’s the message rate? Aedes provides events you can use to track this.
aedes.on('client', function (client) {
console.log(`New client: ${client.id}`);
// Log to a monitoring system
});
aedes.on('publish', function (packet, client) {
if (client) {
// Count messages per client
}
});
Building this myself solved my smart home problems. My sensors now connect reliably, and their batteries last weeks, not days. The system handles hundreds of devices without breaking a sweat.
The true power of MQTT lies in its simplicity and its fit for purpose. It doesn’t try to be everything for everyone. It excels at moving small pieces of data between many devices efficiently. Whether you’re tracking vehicles, building a chat app, or monitoring industrial machines, this pattern works.
Have you ever struggled with real-time data in your projects? What was the main challenge? For me, it was always the overhead and complexity. MQTT cut through that.
I encourage you to take this foundation and experiment. Start with a simple broker and two clients. Try different QoS levels. Add authentication. See how the wildcard subscriptions work. The hands-on experience is worth more than any theory.
I hope this guide helps you build something amazing. If you found it useful, please share it with someone who might be battling similar connectivity issues. I’d love to hear about your projects in the comments below. What will you connect first?
As a best-selling author, I invite you to explore my books on Amazon. Don’t forget to follow me on Medium and show your support. Thank you! Your support means the world!
101 Books
101 Books is an AI-driven publishing company co-founded by author Aarav Joshi. By leveraging advanced AI technology, we keep our publishing costs incredibly low—some books are priced as low as $4—making quality knowledge accessible to everyone.
Check out our book Golang Clean Code available on Amazon.
Stay tuned for updates and exciting news. When shopping for books, search for Aarav Joshi to find more of our titles. Use the provided link to enjoy special discounts!
📘 Checkout my latest ebook for free on my channel!
Be sure to like, share, comment, and subscribe to the channel!
Our Creations
Be sure to check out our creations:
Investor Central | Investor Central Spanish | Investor Central German | Smart Living | Epochs & Echoes | Puzzling Mysteries | Hindutva | Elite Dev | JS Schools
We are on Medium
Tech Koala Insights | Epochs & Echoes World | Investor Central Medium | Puzzling Mysteries Medium | Science & Epochs Medium | Modern Hindutva