CoAP, the Constrained Application Protocol, is what you get when you take the ideas of the web, resources identified by URLs and manipulated with GET, PUT, POST and DELETE, and rebuild them for a device with a few kilobytes of RAM and a radio that can carry only small packets. It was standardized by the IETF as RFC 7252 in 2014, designed alongside 6LoWPAN so that battery-powered sensors on IEEE 802.15.4 radios could be first-class participants in an IP network.
Where MQTT is a messaging protocol built around a central broker, CoAP is a request-response protocol in which devices are servers that expose resources and clients that call them. The two solve overlapping problems with different shapes, and the choice between them is one of the recurring decisions in IoT design. This guide explains how CoAP works, what makes it suitable for the smallest devices, and where it fits.
REST for small devices
A CoAP server, which might be a thermostat, exposes resources at paths such as /temperature or /setpoint. A client sends a request with a method and a path and gets a response with a code and a payload, exactly like HTTP:
GET coap://[2001:db8::1]/temperature
-> 2.05 Content {"t": 21.4}
PUT coap://[2001:db8::1]/setpoint {"t": 20.0}
-> 2.04 Changed
The methods are GET, POST, PUT and DELETE, and later extensions added FETCH, PATCH and iPATCH. Response codes mirror HTTP classes (2.xx success, 4.xx client error, 5.xx server error) in a compact form. Content is described by a numeric content-format option rather than a long media type string, and CBOR is the natural payload encoding since it is a binary form of the JSON data model that costs far fewer bytes.
Because the model matches HTTP so closely, a proxy can translate between the two with little loss, which is what allows constrained devices to fit into REST API architectures.
Why UDP
CoAP runs over UDP rather than TCP. TCP requires state, buffers and a handshake for every connection, which is costly in memory and in radio time for a device that wakes briefly to send one reading. UDP is stateless: a request is one datagram, a response is another, and a four-byte CoAP header plus options fits comfortably in the small frames that 802.15.4 and LPWAN radios carry.
Reliability, where needed, is handled by CoAP itself. Each message is one of four types:
- Confirmable (CON): the sender expects an acknowledgment and retransmits with exponential backoff until it gets one.
- Non-confirmable (NON): fire and forget, for readings where the next one will supersede a lost one.
- Acknowledgment (ACK): confirms a CON message, and can carry the response in the same packet (a piggybacked response).
- Reset (RST): signals that a message could not be processed.
A response that takes longer than the acknowledgment window can be sent separately, so a server can acknowledge immediately and respond when it has the data. Message IDs match requests to acknowledgments, and tokens match requests to responses, which is how a client handles many outstanding requests at once.
Observe: push without a broker
A plain request-response model would force a client to poll a sensor, which wastes the sensor’s energy. The Observe extension (RFC 7641) fixes this. A client sends a GET with the Observe option, and the server adds it to a list of observers for that resource. Whenever the resource changes, the server sends a notification to each observer, using the original token. The client sees a stream of responses to one request.
Observe gives CoAP a publish-subscribe flavor, but with the relationship held directly between the client and the device rather than through a broker. That is lighter but less decoupled: the client must know the device’s address, and the device must keep state for each observer. For many-to-many distribution a broker-based protocol remains simpler.
Block-wise transfer
A single UDP datagram over a constrained radio carries at most a few dozen to a few hundred bytes. Firmware images and large configurations do not fit. Block-wise transfer (RFC 7959) splits a payload into numbered blocks that are requested or sent one at a time, each fitting in a single datagram, with the receiver able to control the block size. This is how CoAP devices receive OTA updates.
Discovery
A CoAP server can describe its own resources. A GET on /.well-known/core returns a list of resource paths with their types in the CoRE Link Format, so a commissioning tool or gateway can discover what a newly joined device offers without a product-specific driver. Multicast requests let a client find every device on a link in one query.
Security with DTLS and OSCORE
Since CoAP runs over UDP, it cannot use TLS directly. The standard security layer is DTLS, a version of TLS adapted to datagrams, with pre-shared keys, raw public keys or X.509 certificates for authentication. The secure variant uses the coaps scheme. The DTLS handshake is the most expensive thing a constrained device does, so session resumption and long-lived sessions matter.
DTLS protects the hop between the device and its peer, but a proxy in the middle terminates it and sees everything. Object Security for Constrained RESTful Environments (OSCORE, RFC 8613) encrypts the CoAP message itself so that it stays protected end to end through proxies, which suits deployments where a gateway or a third-party network sits between device and application.
CoAP in the ecosystem
CoAP is the transport for LwM2M, the OMA SpecWorks device management standard, which defines a standard set of resources for device information, connectivity, firmware update and sensors on top of CoAP. Cellular IoT modules and many constrained-device operating systems implement LwM2M, so choosing CoAP often means getting management for free.
CoAP is also the native application protocol for Thread networks, where it is used both for Thread’s own commissioning and management and by applications. Matter chose its own interaction model rather than CoAP, but runs over the same UDP and IPv6 foundation.
Choosing between CoAP and MQTT
Use CoAP when the device is genuinely constrained: a few kilobytes of RAM, a low-power radio, a need to sleep most of the time, or a network that cannot carry TCP well. Use it when the interaction is naturally request-response, when devices need to be addressed directly by other devices or gateways, when discovery matters, or when you are already in the LwM2M or Thread world.
Use MQTT when devices have an IP connection with a reasonable stack, when many consumers need the same data, when you want a broker to hold messages for offline devices, or when the platform you are using expects it. Most cloud IoT platforms speak MQTT first and CoAP, if at all, through a gateway.
The two are not exclusive: a common architecture has constrained devices speaking CoAP to a local gateway, which republishes over MQTT to the cloud.
Where to go next
- MQTT explained describes the broker-based alternative in detail.
- Thread explained covers the IPv6 mesh network where CoAP is native.
- Types of IoT devices and their constraints explains why some devices cannot afford TCP.
- IoT connectivity overview covers the radios CoAP typically runs over.
Topics: CoAP, protocols, UDP, constrained devices, REST