MQTT Protocol Explained for ESP32

A conceptual, easy-to-follow guide to understanding why MQTT is the backbone of modern IoT communication

1. Introduction

MQTT (Message Queuing Telemetry Transport) is one of the most widely used communication protocols in the Internet of Things (IoT) world. It powers everything from home automation systems to industrial sensor networks, and it is the go-to choice for ESP32-based projects that need to send or receive data over Wi-Fi.

MQTT is not tied to any single platform — it is supported by cloud services, mobile apps, microcontrollers like the ESP32, and desktop applications alike, which is exactly why it has become the standard for IoT messaging.

2. Understanding Traditional Client-Server Communication

Before diving into MQTT, it helps to understand how a normal client-server connection works. In this model, a server is a program that stores and manages data, while a client is a device or program that connects to the server to send or request data.

Server Client 1 Client 2

When Client 1 sends data, the server stores it temporarily or permanently. If Client 2 later wants that same data, it must send a request to the server, which then looks up the stored data and replies. This works well for small, simple applications, and the speed of communication depends on the underlying protocol — for example, a raw TCP socket connection is much faster than an HTTP-based request.

3. The Problem: Scaling to Many Devices

Now imagine a scenario with one server and hundreds — or even thousands — of clients, all wanting access to data from one another. Every client would need to request data individually from every other client, creating a tangled, inefficient mesh of connections.

Server

A growing mesh of clients requesting data from a single server becomes complex and inefficient.

This is exactly the kind of scenario where a smarter communication model is needed — and that is where MQTT comes in.

4. How MQTT Solves This: The Broker Model

MQTT follows the same basic client-server idea, but changes the roles and terminology to make communication far more efficient:

Broker Client 1 (Publisher: temp/humidity) Client 2 (Mobile App) Subscriber: temp + humidity Client 3 Subscriber: humidity only

In this model, Client 1 (for example, an ESP32 with a DHT22 sensor) publishes temperature and humidity readings to two topics. Client 2, a mobile app, has subscribed to both topics, so it instantly receives both values. Client 3 has only subscribed to humidity, so it only receives that value — with no polling and no manual request required.

Key Insight: No Storage Required

The broker's job is to relay, not to permanently store, data. As soon as a publisher sends a message, it is instantly forwarded to every currently subscribed client. Persistent storage on the broker is optional (useful for logging or retained messages), but it is not a requirement for the protocol to work — this is what makes MQTT communication so fast.

Publisher and Subscriber Are Not Fixed Roles

A single device can act as both a publisher and a subscriber at the same time. For example, an ESP32 might publish sensor readings on the temp and humidity topics, while simultaneously subscribing to an led topic to receive on/off commands from a mobile app.

Role Action Example Topic
Publisher ESP32 Sensor Node Sends temperature & humidity readings home/temp, home/humidity
Subscriber Mobile App Receives readings for display home/temp, home/humidity
Subscriber ESP32 (same device) Listens for LED control commands home/led
Publisher Mobile App Sends "on"/"off" command home/led

5. Practical Example: ESP32 Weather Station with LED Control

Let's walk through a simple real-world scenario using the roles described above. Below is the conceptual flow of MQTT topics and messages — not full source code, but the sequence of commands/messages you would conceptually issue when working with an MQTT client library (such as PubSubClient on the ESP32).

Step 1 — Connect the ESP32 to the Broker

// Connect to Wi-Fi network WiFi.begin(ssid, password); // Connect to the MQTT broker client.setServer(mqtt_broker_ip, 1883); client.connect("esp32_client");

Step 2 — Publish Sensor Data

// Publish temperature reading client.publish("home/temp", "30"); // Publish humidity reading client.publish("home/humidity", "40");

Step 3 — Subscribe to the LED Control Topic

// Subscribe to receive LED commands client.subscribe("home/led");

Step 4 — Handle Incoming Messages

// Callback triggered when a message arrives void callback(char* topic, byte* payload, unsigned int length) {   if (String(topic) == "home/led") {     if (payload[0] == '1') digitalWrite(LED_PIN, HIGH);     else digitalWrite(LED_PIN, LOW);   } }
Notice how each instruction represents one distinct action — connect, publish, subscribe, and handle — kept on its own line rather than merged into a single block. This mirrors how MQTT operations are logically separated: connecting, sending, and listening are independent steps.

6. Summary

MQTT is often described as a lightweight publish/subscribe messaging transport, ideal for constrained devices like the ESP32 and unreliable or low-bandwidth networks. Its strength comes from three simple ideas:

What's Next?

In a follow-up practical session, you would typically install an MQTT broker (such as Mosquitto), configure an ESP32 with the PubSubClient library, and build a working publish/subscribe demo combining a real sensor and an actuator like an LED or relay.