> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# MQTT Protocol

> Understanding the MQTT protocol - the foundation of IoT communication.

## The Language of IoT

MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe messaging protocol designed for constrained devices and low-bandwidth, high-latency networks. It has become the de facto standard for IoT communication.

Before diving into Coreflux features like LoT Actions and Models, you need to understand how MQTT works. Every Coreflux capability builds on these fundamentals—topics, subscriptions, QoS, and message patterns.

<Tip>
  **Think of MQTT like a radio station.** Publishers broadcast on a frequency (topic), and anyone who tunes in (subscribes) hears the message. The broker is the transmission tower that makes it all work.
</Tip>

<Info>
  MQTT is designed to be simple, lightweight, and easy to implement. A minimal MQTT control message can be as small as 2 bytes, making it ideal for resource-constrained devices.
</Info>

***

## In This Page

| Section                                                         | Description                              |
| --------------------------------------------------------------- | ---------------------------------------- |
| [The Publish-Subscribe Pattern](#the-publish-subscribe-pattern) | How MQTT decouples senders and receivers |
| [Topics](#topics)                                               | The routing mechanism for messages       |
| [Wildcards](#wildcards)                                         | Subscribe to multiple topics at once     |
| [Quality of Service](#quality-of-service-qos)                   | Message delivery guarantees              |
| [Retained Messages](#retained-messages)                         | Store last message for new subscribers   |
| [Last Will and Testament](#last-will-and-testament-lwt)         | Handle unexpected disconnections         |

***

## The Publish-Subscribe Pattern

Unlike traditional request-response protocols (like HTTP), MQTT uses a publish-subscribe (pub/sub) pattern. This decouples the sender (publisher) from the receiver (subscriber), allowing for more flexible and scalable architectures.

```mermaid theme={null}
flowchart LR
    subgraph Publishers
        A[Temperature Sensor]
        B[Humidity Sensor]
    end
    subgraph Broker
        C[Coreflux MQTT Broker]
    end
    subgraph Subscribers
        D[Mobile App]
        E[Dashboard]
        F[Database]
    end
    A -->|"PUBLISH<br/>sensors/temp"| C
    B -->|"PUBLISH<br/>sensors/humidity"| C
    C -->|"DELIVER"| D
    C -->|"DELIVER"| E
    C -->|"DELIVER"| F
```

### How It Works

<Steps>
  <Step title="Publisher sends message">
    A client publishes a message to a specific topic on the broker.
  </Step>

  <Step title="Broker receives message">
    The broker receives the message and checks which clients are subscribed to that topic.
  </Step>

  <Step title="Broker delivers message">
    The broker forwards the message to all subscribers of that topic.
  </Step>
</Steps>

***

## Topics

Topics are the routing mechanism in MQTT. They are UTF-8 strings that the broker uses to filter messages for each connected client.

### Topic Structure

Topics are hierarchical, using forward slashes (`/`) as level separators. This hierarchy is powerful for organizing data—especially in industrial settings using patterns like the Unified Namespace (UNS).

```
building/floor1/room101/temperature
building/floor1/room101/humidity
building/floor2/room201/temperature
```

### Topic Tree Example

A well-designed topic tree organizes your entire system logically:

```mermaid theme={null}
flowchart LR
    A[enterprise] --> B[site] --> C[area] --> D[line] --> E[cell] --> F[device] --> G[measurement]
```

Here's how this maps to real topics:

```
enterprise/
├── factory-munich/
│   ├── production/
│   │   ├── line-1/
│   │   │   ├── cnc-machine-01/
│   │   │   │   ├── temperature
│   │   │   │   ├── vibration
│   │   │   │   └── status
│   │   │   └── robot-arm-02/
│   │   │       ├── position
│   │   │       └── status
│   │   └── line-2/
│   │       └── ...
│   └── quality/
│       └── ...
└── factory-berlin/
    └── ...
```

<Tip>
  Design your topic hierarchy carefully. A well-structured topic tree—often called a Unified Namespace (UNS)—makes it easier to subscribe to related data, manage access control, and scale your system.
</Tip>

### Topic Best Practices

| Practice                   | Example                            | Description                       |
| -------------------------- | ---------------------------------- | --------------------------------- |
| Use hierarchical structure | `factory/line1/machine1/status`    | Organize topics logically         |
| Be specific                | `sensors/temp/celsius`             | Avoid overly generic topics       |
| Use lowercase              | `home/living-room/light`           | Consistent naming convention      |
| Avoid leading slashes      | `home/kitchen` not `/home/kitchen` | Leading slash creates empty level |

***

## Wildcards

MQTT supports two wildcard characters for subscribing to multiple topics at once.

<Tabs>
  <Tab title="Single-Level (+)">
    The `+` wildcard matches **exactly one** topic level.

    **Subscription:** `building/floor1/+/temperature`

    <Check>
      **Matches:** `building/floor1/room101/temperature`, `building/floor1/room102/temperature`, `building/floor1/lobby/temperature`
    </Check>

    <Warning>
      **Does NOT match:** `building/floor2/room201/temperature` (different floor), `building/floor1/room101/humidity` (different measurement), `building/floor1/west/room101/temperature` (extra level)
    </Warning>
  </Tab>

  <Tab title="Multi-Level (#)">
    The `#` wildcard matches **any number of levels** and must be at the end.

    **Subscription:** `building/floor1/#`

    <Check>
      **Matches:** `building/floor1/room101/temperature`, `building/floor1/room101/humidity`, `building/floor1/room102/status`, `building/floor1/lobby/motion/detected`
    </Check>

    <Warning>
      **Does NOT match:** `building/floor2/room201/temperature` (different floor), `building/basement/storage/humidity` (different path)
    </Warning>
  </Tab>
</Tabs>

<Warning>
  Use wildcards carefully. Subscribing to `#` alone would receive ALL messages on the broker, which could overwhelm your client and create security risks.
</Warning>

***

## Quality of Service (QoS)

MQTT defines three levels of Quality of Service for message delivery. Choose based on your reliability requirements and network conditions.

### QoS 0 — At Most Once

**Fire and forget.** The message is sent once with no acknowledgment.

```mermaid theme={null}
sequenceDiagram
    participant P as Publisher
    participant B as Broker
    participant S as Subscriber
    P->>B: PUBLISH
    B->>S: PUBLISH
```

| Aspect             | Detail                                                       |
| ------------------ | ------------------------------------------------------------ |
| **Delivery**       | At most once (may be lost)                                   |
| **Acknowledgment** | None                                                         |
| **Performance**    | Fastest                                                      |
| **Use when**       | Frequent sensor readings where occasional loss is acceptable |

<Note>
  **Best for:** High-frequency telemetry data like temperature readings every second. Missing one reading doesn't matter when the next arrives immediately.
</Note>

### QoS 1 — At Least Once

**Acknowledged delivery.** The sender stores the message until the broker confirms receipt.

```mermaid theme={null}
sequenceDiagram
    participant P as Publisher
    participant B as Broker
    participant S as Subscriber
    P->>B: PUBLISH
    B->>S: PUBLISH
    B->>P: PUBACK
```

| Aspect             | Detail                                                      |
| ------------------ | ----------------------------------------------------------- |
| **Delivery**       | At least once (may duplicate)                               |
| **Acknowledgment** | PUBACK from broker                                          |
| **Performance**    | Moderate                                                    |
| **Use when**       | Important data where your application can handle duplicates |

<Note>
  **Best for:** Event logs, alerts, or status updates. If the same alert arrives twice, your system should deduplicate it.
</Note>

### QoS 2 — Exactly Once

**Assured delivery.** A four-way handshake ensures the message arrives exactly once.

```mermaid theme={null}
sequenceDiagram
    participant P as Publisher
    participant B as Broker
    P->>B: PUBLISH
    B->>P: PUBREC
    P->>B: PUBREL
    B->>P: PUBCOMP
```

| Aspect             | Detail                                        |
| ------------------ | --------------------------------------------- |
| **Delivery**       | Exactly once (guaranteed, no duplicates)      |
| **Acknowledgment** | PUBREC → PUBREL → PUBCOMP handshake           |
| **Performance**    | Slowest                                       |
| **Use when**       | Critical data where duplicates cause problems |

<Note>
  **Best for:** Financial transactions, billing events, or commands where duplicate execution would be harmful (e.g., "dispense medication").
</Note>

***

## Retained Messages

When a message is published with the retain flag set, the broker stores the last message for that topic. Any new subscriber immediately receives this retained message upon subscribing.

<Tip>
  Retained messages are useful for status topics. A new client connecting can immediately know the current state without waiting for the next update.
</Tip>

**Example use cases:**

* Device status (online/offline)
* Current configuration values
* Last known sensor readings

***

## Last Will and Testament (LWT)

The Last Will and Testament feature allows a client to specify a message that the broker should publish if the client disconnects unexpectedly. This is essential for detecting device failures.

### How LWT Works

```mermaid theme={null}
sequenceDiagram
    participant D as Device
    participant B as Broker
    participant M as Monitoring System
    
    D->>B: CONNECT with LWT
    Note right of B: LWT stored:<br/>"devices/sensor-01/status" = "offline"
    
    D->>B: PUBLISH status = "online"
    B->>M: status = "online"
    
    Note over D: Device crashes or<br/>loses network
    
    B->>M: LWT triggered:<br/>status = "offline"
```

<Steps>
  <Step title="Client connects with LWT">
    When connecting, the client specifies its LWT message, topic, QoS, and retain flag.
  </Step>

  <Step title="Connection maintained">
    The broker holds the LWT message as long as the client stays connected.
  </Step>

  <Step title="Unexpected disconnect">
    If the client disconnects without sending a proper DISCONNECT packet (crash, network loss), the broker publishes the LWT message.
  </Step>
</Steps>

### LWT Configuration Example

A typical pattern for device status monitoring:

| Setting         | Value                      | Purpose                                |
| --------------- | -------------------------- | -------------------------------------- |
| **LWT Topic**   | `devices/sensor-01/status` | Where to publish if device disconnects |
| **LWT Message** | `offline`                  | What to publish                        |
| **LWT Retain**  | `true`                     | Keep message for new subscribers       |
| **LWT QoS**     | `1`                        | Ensure delivery to monitoring systems  |

When the device connects, it publishes `online` to the same topic (retained). If it crashes, the broker publishes `offline`. Monitoring systems always know the current state.

***

## Clean Sessions

MQTT supports two session types:

| Session Type           | Clean Session Flag | Behavior                                                                           |
| ---------------------- | ------------------ | ---------------------------------------------------------------------------------- |
| **Clean Session**      | `true`             | No state is stored between connections. Subscriptions are discarded on disconnect. |
| **Persistent Session** | `false`            | Broker stores subscriptions and queued messages (QoS 1/2) for the client.          |

<Note>
  Persistent sessions are useful for mobile devices or intermittent connections where you don't want to miss messages during brief disconnections.
</Note>

***

## Keep Alive

The keep-alive mechanism ensures the connection remains active and detects dead connections quickly.

```mermaid theme={null}
sequenceDiagram
    participant C as Client
    participant B as Broker
    
    C->>B: CONNECT (keep-alive: 60s)
    
    Note over C,B: Normal data exchange
    C->>B: PUBLISH
    B->>C: PUBACK
    
    Note over C,B: No data to send...<br/>approaching keep-alive timeout
    
    C->>B: PINGREQ
    B->>C: PINGRESP
    
    Note over C,B: Connection confirmed alive
    
    C->>B: PINGREQ
    Note over B: No PINGRESP for 1.5x keep-alive
    Note over B: Connection declared dead,<br/>LWT published
```

### How It Works

| Step            | Description                                                                                     |
| --------------- | ----------------------------------------------------------------------------------------------- |
| **1. Connect**  | Client specifies a keep-alive interval (in seconds) when connecting                             |
| **2. Activity** | Client must send a control packet within each keep-alive period                                 |
| **3. Ping**     | If no data is being sent, the client sends PINGREQ                                              |
| **4. Response** | The broker responds with PINGRESP                                                               |
| **5. Timeout**  | If no communication occurs within 1.5x the keep-alive period, the connection is considered dead |

<Tip>
  Choose keep-alive values based on your network. Shorter intervals (15-30s) detect failures faster but use more bandwidth. Longer intervals (60-120s) are better for mobile networks with variable latency.
</Tip>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Broker Commands" icon="terminal" href="/mqtt-broker/commands">
    Learn how to control the Coreflux broker via MQTT commands.
  </Card>

  <Card title="$SYS Topics" icon="sitemap" href="/mqtt-broker/sys-topics">
    Explore system topics for monitoring and control.
  </Card>
</CardGroup>
