What Is MQTT?

MQTT (Message Queuing Telemetry Transport) is a lightweight publish-subscribe messaging protocol designed for constrained devices and low-bandwidth networks. It's the backbone of countless IoT systems — from smart home sensors to industrial monitoring — because it's simple, efficient, and reliable even over unstable connections.

In an MQTT system, devices (clients) connect to a central broker. Clients can publish messages to named topics, and other clients can subscribe to those topics to receive the messages. No direct device-to-device communication is needed.

Key MQTT Concepts

  • Broker: The server that routes messages. Popular options include Mosquitto (self-hosted) and HiveMQ Cloud (managed).
  • Topic: A string that acts like an address, e.g., home/livingroom/temperature
  • Publish: Sending a message to a topic
  • Subscribe: Registering to receive messages from a topic
  • QoS (Quality of Service): 0 = fire and forget, 1 = at least once, 2 = exactly once

Setting Up a Mosquitto Broker

If you have a Raspberry Pi or a local server, you can run a free Mosquitto broker:

# On Raspberry Pi / Ubuntu
sudo apt update
sudo apt install mosquitto mosquitto-clients
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

Alternatively, use a free cloud broker like HiveMQ Public Broker (broker.hivemq.com, port 1883) for testing — no setup required.

Installing the PubSubClient Library

In Arduino IDE, go to Sketch → Include Library → Manage Libraries and search for PubSubClient by Nick O'Leary. This is the standard MQTT client library for Arduino-based ESP32 projects.

ESP32 MQTT Example: Publish Sensor Data

#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const char* mqtt_server = "broker.hivemq.com";

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP32Client")) {
      client.subscribe("home/commands");
    } else {
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  String msg = "";
  for (int i = 0; i < length; i++) msg += (char)payload[i];
  Serial.println("Received: " + msg);
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();
  // Publish a reading every 5 seconds
  static unsigned long last = 0;
  if (millis() - last > 5000) {
    client.publish("home/temperature", "22.5");
    last = millis();
  }
}

Integrating with Home Assistant

If you run Home Assistant, you can add an MQTT integration in just a few clicks. Once configured, any message your ESP32 publishes to a topic like homeassistant/sensor/esp32temp/state can automatically appear as a sensor entity on your dashboard — enabling automations, alerts, and historical graphs.

Tips for Reliable MQTT on ESP32

  1. Use a unique client ID for each device to avoid connection conflicts.
  2. Implement a reconnect loop — Wi-Fi and broker connections can drop.
  3. Keep payloads small and use QoS 1 for important messages.
  4. Use retained messages so new subscribers immediately get the last known value.
  5. Secure your broker with username/password authentication in production.