MQTT Fundamentals

MQTT vs CoAP: TCP Pub/Sub vs UDP Request/Response

MQTT and CoAP both target constrained IoT devices but take opposite approaches: brokered pub/sub over TCP versus RESTful request/response over UDP. Here is how they compare and when to use each.

Illustration of a sensor sending UDP datagrams to a CoAP server beside a sensor connected over TCP to a broker, comparing MQTT vs CoAP
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

MQTT vs CoAP is a choice between two protocols built for the same kind of hardware, small battery-powered devices on lossy networks, that nevertheless work in opposite ways. MQTT is publish/subscribe over TCP through a broker; CoAP is RESTful request/response over UDP, directly between endpoints. This guide compares transports, headers, security, multicast and data flow, so you can decide which fits your devices and your backend.

The Short Version

If your devices can hold a TCP connection and your data needs to reach several consumers in the cloud, MQTT with a broker is usually the simpler path. If your devices sit on a constrained IPv6 network such as 6LoWPAN or Thread, sleep most of the time and are addressed like tiny web servers, CoAP is a natural fit. Many large deployments use CoAP on the local constrained network and MQTT from a gateway to the cloud.

How CoAP Works

CoAP (Constrained Application Protocol, RFC 7252) brings the REST model to microcontrollers. Each device exposes resources such as /sensors/temp, and clients use GET, POST, PUT and DELETE on them, just like HTTP but in a compact binary format over UDP. Responses carry codes modeled on HTTP status codes, for example 2.05 Content or 4.04 Not Found.

Because UDP has no delivery guarantee, CoAP adds its own lightweight reliability: a message can be Confirmable (CON), which the receiver must acknowledge, or Non-confirmable (NON), which is fire-and-forget. Retransmissions use exponential backoff.

CoAP also has an Observe option (RFC 7641). A client registers interest in a resource and the server sends a notification each time it changes. It is the closest thing CoAP has to MQTT's subscribe, but it is point-to-point between a client and one server.

How MQTT Works

MQTT clients open a TCP connection (optionally TLS) to a broker, then publish messages to topics and subscribe to topic filters. Devices never talk to each other directly; the broker handles fan-out, retained last-known values, persistent sessions for offline subscribers and Last Will messages for ungraceful disconnects. If the broker concept is new to you, start with what an MQTT broker is, and for a step-by-step introduction see the MQTT tutorial.

MQTT vs CoAP at a Glance

Aspect MQTT CoAP
Standard OASIS MQTT 3.1.1 and 5.0 IETF RFC 7252 and extensions
Transport TCP (or WebSocket over TCP) UDP (TCP and WebSocket variants exist in RFC 8323)
Pattern Publish/subscribe through a broker Request/response between endpoints, plus Observe
Header 2-byte minimum fixed header, plus topic 4-byte fixed header, plus token and options
Reliability TCP plus QoS 0, 1, 2 Confirmable and non-confirmable messages
Security TLS DTLS (or OSCORE for object security)
Discovery None in the protocol; topics are conventions /.well-known/core resource discovery
Multicast No Yes, over IP multicast for group requests
Fan-out to many consumers Native through broker Requires a proxy or each client to observe
Offline handling Persistent sessions, retained messages Device must be reachable or proxied
NAT and firewall traversal Easy: device opens outbound TCP Harder: UDP mappings expire
Typical network Wi-Fi, Ethernet, cellular, gateways 6LoWPAN, Thread, constrained IPv6 meshes

Transport: TCP vs UDP

The transport is the root of most differences. TCP gives MQTT ordered, reliable byte streams, but it costs a three-way handshake to connect and keeps state on both ends. On a lossy radio link, TCP retransmissions and head-of-line blocking can add latency. For more on the transport question, see is MQTT TCP or UDP.

UDP lets CoAP send a reading in a single datagram with no connection setup, which suits devices that wake briefly, transmit and go back to sleep. The trade-off is that the application, CoAP in this case, must handle reliability, deduplication and congestion control itself, and that devices behind NAT become hard to reach because UDP mappings time out quickly.

Header Size and Overhead

Both protocols are compact. An MQTT PUBLISH can be very small, but the topic string travels with every message unless you use MQTT 5 topic aliases. CoAP uses a 4-byte header, a short token and options encoded as deltas, so the URI path is also compact. In practice, per-message overhead is in the same small range for both; the bigger difference is connection overhead (TCP and TLS for MQTT versus none or DTLS for CoAP).

Security: TLS vs DTLS

MQTT uses TLS over TCP, the same well-understood stack that protects HTTPS, with mature support in device SDKs, gateways and cloud brokers. A managed broker typically handles certificates for you; ConnectMQ, for example, serves a Let's Encrypt certificate on port 8883 for TLS and 8084 for secure WebSocket.

CoAP uses DTLS, the datagram version of TLS. It works, but session state, handshake retransmission over lossy links and NAT rebinding add complexity, and tooling is less widespread. OSCORE (RFC 8613) offers end-to-end object security that survives proxies, which is attractive in multi-hop constrained networks but adds its own key management.

For either protocol, the practical rule is the same: encrypt every hop that leaves the device, and never rely on network isolation alone. The MQTT security best practices guide covers credentials, TLS and topic design for MQTT deployments.

Observe vs Subscribe

CoAP Observe and MQTT subscribe both deliver updates without polling, but the topology differs. With Observe, every interested client registers with the device itself. Ten dashboards mean ten observers on a microcontroller that may have kilobytes of RAM. With MQTT, the device publishes once to the broker and the broker handles any number of subscribers. That is why MQTT scales better when data has many consumers, while CoAP works well when one controller talks to many small devices.

Multicast and Local Discovery

This is CoAP's clear advantage. A client can send one request to an IP multicast group, for example to turn off every light on a floor, and every member responds. Combined with resource discovery at /.well-known/core, CoAP suits local building and home automation networks where devices find each other without a central server. MQTT has no multicast; every message goes through the broker.

A Common Hybrid Pattern

Constrained mesh networks and the cloud have different needs, so many systems put a gateway between them:

  1. Sensors on a Thread or 6LoWPAN mesh expose CoAP resources.
  2. A border gateway observes those resources or receives CoAP POSTs.
  3. The gateway publishes each update over MQTT with TLS to a cloud MQTT broker, for example to site1/floor2/room14/temperature.
  4. Dashboards, historians and alerting services subscribe to the broker.

Here is the cloud side of that gateway in Python. The CoAP handling depends on your library, so it is represented by a function that receives a reading; the MQTT part is complete.

import json
import ssl
import time
import paho.mqtt.client as mqtt

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.will_set("site1/gateway1/status", "offline", qos=1, retain=True)

def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    client.publish("site1/gateway1/status", "online", qos=1, retain=True)

client.on_connect = on_connect
client.connect("broker.connectmq.com", 8883, keepalive=60)
client.loop_start()

def forward_coap_reading(resource_path, value):
    """Call this from your CoAP observe callback."""
    topic = "site1/" + resource_path.strip("/").replace("sensors/", "")
    payload = json.dumps({"value": value, "ts": int(time.time())})
    client.publish(topic, payload, qos=1, retain=True)

# Example: a reading observed from coap://[fd00::12]/sensors/floor2/room14/temperature
forward_coap_reading("/sensors/floor2/room14/temperature", 21.6)
time.sleep(2)

To experiment without an account, swap the connection for client.connect("broker.connectmq.com", 1883) with any unique client ID and a topic prefix such as connectmq/demo/<random-id>/, but keep in mind that the free public MQTT broker is readable by everyone.

When to Choose Which

Choose MQTT when:

  • Devices are on Wi-Fi, Ethernet or cellular and can keep an outbound TCP connection.
  • Data needs to reach several cloud consumers.
  • You want retained state, online status via Last Will and buffering for offline subscribers.
  • You prefer mature, widely available client libraries and managed hosting.

Choose CoAP when:

  • Devices run on constrained IPv6 meshes with very limited RAM and power.
  • You need multicast commands or local discovery without a central server.
  • The interaction is naturally request/response, such as reading or writing a device setting.

If your project sits closer to the MQTT side but devices are extremely constrained or non-TCP, also look at MQTT-SN, which brings MQTT semantics to UDP and other datagram transports.

Get Started with ConnectMQ

Whether your devices speak MQTT natively or through a CoAP gateway, the cloud side needs a reliable broker. ConnectMQ is a managed broker with MQTT 3.1.1 and 5.0, TLS on 8883 and a live topic explorer for checking every gateway as it comes online. Create a free Serverless broker at app.connectmq.com, no credit card required, and connect your first gateway in minutes.

Frequently Asked Questions

Is CoAP better than MQTT for battery devices?

It can be for devices that wake rarely and send one datagram, because UDP avoids connection setup. For devices that report often or must receive commands, MQTT's persistent connection is usually just as efficient and simpler to operate.

Does CoAP need a broker?

No. CoAP clients talk directly to device endpoints. Proxies can add caching and protocol translation, but there is no central broker as in MQTT.

Can CoAP and MQTT work together?

Yes. A gateway commonly observes CoAP resources on a local mesh and publishes the values to an MQTT broker in the cloud, giving you local efficiency and cloud fan-out.

Does MQTT support UDP?

Standard MQTT runs over TCP or WebSocket. MQTT-SN is a related protocol designed for UDP and other datagram networks, usually connected to a normal MQTT broker through a gateway.

Related articles

Why Your MQTT Client Keeps Disconnecting (and How to Fix It)

Reconnect loops are one of the most common MQTT problems. Learn the five usual causes, from duplicate client IDs to keep alive timeouts and oversized packets, and follow a diagnosis flow that pinpoints yours.

8 min read

Who Invented MQTT? The History from Oil Pipelines to IoT

MQTT was invented in 1999 by Andy Stanford-Clark of IBM and Arlen Nipper of Arcom to monitor oil pipelines over satellite. Follow its path to open source, OASIS, ISO and today's managed cloud brokers.

7 min read

MQTT Maximum Message Size: Limits and Large Payload Strategies

MQTT can technically carry a 256 MB packet, but brokers, client libraries and devices impose far lower limits. Learn where the real limits are, what happens when you exceed them, and how to send large payloads.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.