Chapters

8 CoAP Methods and Multicast

coap
methods

8.1 Start With the Device Menu

Choose the Action Before the Method

Picture a caretaker using a small panel to read a tank level and change an alarm limit. A read must not alter the device. A repeated update must not create a second record by accident. The action comes first; the message choice must preserve its meaning.

A protocol is a shared set of rules for exchanging messages. Constrained Application Protocol (CoAP) is a compact web-style protocol for small devices and links. A gateway is a device that joins unlike networks. Before choosing a method, write the resource, the allowed action, who may request it, the expected reply, and whether repeating the request is safe.

Test one normal request, one missing resource, one denied change, and one lost reply. Check the device state as well as the screen. If many devices receive the same request, prove that the result stays bounded and that replies do not swamp the link.

This first menu does not settle every transport or security choice. It does expose unsafe meanings early. The deeper sections compare methods, group delivery, updates, and related message systems so the final design matches the action rather than a familiar label.

Imagine a gateway walking up to a sensor and seeing a tiny menu: read temperature, update configuration, create a calibration record, or delete a stale resource. CoAP methods are the verbs on that menu, and the same method has to mean the same thing whether one device calls it or a multicast group hears it.

The chapter starts with the method choice, then adds multicast, Observe, calculators, and comparisons so the learner can see why a compact resource operation is still a full protocol decision.

The mathematical gist. The chapter’s CR2032 model holds 2,430 J at 3.00 V, but the radio sees Vload=VocIRV_{load}=V_{oc}-IR. A 20 mA pulse through 15 ohm loses 0.30 V and reaches 2.70 V; at 100 ohm it loses 2.00 V and reaches only 1.00 V. Its nominal 0.0864 mJ message cost predicts 28,125 days at 1,000 messages/day, about 77.1 years, so a roughly ten-year shelf-life ceiling matters long before that naive message budget runs out.

Math Bridge · guided foundationsHow can a 77-year message budget fail in one pulse?Let Eddie connect nominal joules, internal resistance, cutoff, and shelf life.
Chapter Roadmap

This chapter moves from verbs to deployment choices:

  1. First map GET, POST, PUT, and DELETE to sensor resources.
  2. Then test those methods in Python and ESP32 examples.
  3. Next compare CoAP, MQTT, and HTTP with the byte and battery calculators.
  4. Finally add multicast, discovery, Observe, and CON/NON evidence.

Checkpoint callouts pause the tour; Deep-dive sections and calculation audits are optional support on a first pass.

8.2 Learning Objectives

  • Apply CoAP REST methods (GET, POST, PUT, DELETE) with proper idempotency semantics for IoT resource manipulation
  • Implement CoAP servers and clients using Python (aiocoap) and Arduino (ESP32) for sensor data exchange
  • Configure CoAP multicast addressing for group operations and network-wide resource discovery via /.well-known/core
  • Demonstrate how the CoAP Observe extension enables server-push notifications, reducing energy consumption by up to 99% compared to polling
  • Compare CoAP’s 4-byte header efficiency versus HTTP’s 100+ byte overhead for battery-powered IoT devices
Key Concepts

Read these points as one connected sequence: start with CoAP: Constrained Application Protocol — REST-style request/response protocol using UDP instead of TCP; then Confirmable Message (CON): Requires ACK from recipient — provides reliable delivery over UDP at the cost of one roundtrip; then Non-confirmable Message (NON): Fire-and-forget UDP datagram — lowest latency, no delivery guarantee; then Observe Option: CoAP extension enabling publish/subscribe: client registers to receive notifications on resource changes; then Block-wise Transfer: Fragmentation mechanism for transferring payloads larger than a single CoAP datagram; then Token: Client-generated value matching responses to requests — enables concurrent request/response pairing; and finish with DTLS: Datagram TLS — CoAP’s security layer providing encryption and authentication over UDP.

  • CoAP: Constrained Application Protocol — REST-style request/response protocol using UDP instead of TCP
  • Confirmable Message (CON): Requires ACK from recipient — provides reliable delivery over UDP at the cost of one roundtrip
  • Non-confirmable Message (NON): Fire-and-forget UDP datagram — lowest latency, no delivery guarantee
  • Observe Option: CoAP extension enabling publish/subscribe: client registers to receive notifications on resource changes
  • Block-wise Transfer: Fragmentation mechanism for transferring payloads larger than a single CoAP datagram
  • Token: Client-generated value matching responses to requests — enables concurrent request/response pairing
  • DTLS: Datagram TLS — CoAP’s security layer providing encryption and authentication over UDP

8.3 In 60 Seconds

CoAP supports four REST methods mirroring HTTP: GET (retrieve), POST (create), PUT (update/create), and DELETE (remove), with GET, PUT, and DELETE being idempotent. Beyond basic REST, CoAP adds multicast support for group operations (e.g., turning off all lights), resource discovery via /.well-known/core, and the Observe extension that enables server-push notifications — reducing energy consumption by up to 99% compared to polling.

For Beginners: What is CoAP?

Think about how you communicate with friends. You might send a long email with lots of details, or you might send a quick text message with just the essential information. Both get the message across, but text messages are faster and use less data especially important when you have limited battery or a slow connection.

CoAP is like the text message version of web communication for IoT devices. Regular websites use HTTP, which is like sending detailed emails with lots of extra information in headers and metadata. That works great for powerful computers and smartphones with strong batteries and fast internet. But tiny sensors running on coin batteries can’t afford that luxury. CoAP strips away all the unnecessary extras and keeps just the essential parts: what you want to do, which resource you’re accessing, and the actual data.

The magic is that CoAP still works like the web you know. You can GET data from a sensor, PUT a new setting to a device, or POST a command just like with regular websites. But instead of using hundreds of bytes of overhead like HTTP, CoAP uses just 4 bytes for its header. This means a temperature sensor can report readings for years on a single battery instead of months, and devices can communicate even over slow, unreliable networks where every byte matters.

CoAP Request Methods and Multicast

“CoAP has four magic words that do everything!” announced the microcontroller. “GET means ‘tell me your value.’ PUT means ‘change your setting to this.’ POST means ‘do this action.’ And DELETE means ‘remove this thing.’”

Temperature Terry demonstrated: “When the dashboard sends me a GET, I reply with my temperature. When someone sends a PUT to change my sampling rate from 10 to 30 seconds, I update my setting and confirm. It’s just like asking and answering questions!”

“And multicast is the coolest feature!” added the LED. “Instead of asking each sensor one by one — ‘Sammy, what’s your temperature? Bella, what’s your voltage?’ — you shout to ALL sensors at once: ‘Everyone, report your temperature!’ One message, fifty replies. Imagine how much time and energy that saves in a building with hundreds of sensors!”

the battery loved that. “One multicast GET instead of fifty individual GETs means I save 98% of my radio energy for discovery. It’s like a teacher taking attendance by saying ‘raise your hand if you’re here’ instead of calling each name individually!”

8.4 Continue: CoAP Method Codes and Multicast Contracts

The main chapter below stays focused on the core methods and feature tour. For the deeper contract behind compact method and response codes, safe/idempotent retry behavior, multicast discovery, Location options, Token correlation, and Leisure response spreading, continue to CoAP Method Codes and Multicast Contracts.

8.5 CoAP Methods

Start with the verb contract. If the method is wrong, retries and troubleshooting become ambiguous even when the URI looks sensible.

Like HTTP, CoAP uses REST methods:

MethodPurposeHTTP EquivalentIdempotent
GETRetrieve resourceGETYes
POSTCreate resourcePOSTNo
PUTUpdate/CreatePUTYes
DELETERemove resourceDELETEYes

8.5.1 Examples

Read the examples by the state transition each method promises. GET retrieves the current /temperature representation without changing it. POST sends a new reading to the /readings collection, allowing the server to create a subordinate resource. PUT replaces the known /config representation with the supplied interval, so an identical retry has the same intended state. DELETE removes /readings/old. URI, method, payload, and expected response code should be reviewed together before any of these exchanges is implemented.

GET: Retrieve temperature

coap://sensor.local/temperature

POST: Add new sensor reading

coap://server.local/readings
Payload: {"temp": 23.5, "time": "2025-10-24T23:30:00Z"}

PUT: Update configuration

coap://device.local/config
Payload: {"interval": 60}

DELETE: Remove old data

coap://server.local/readings/old

Broker BexCheckpoint: Method Semantics

You now know:

  • CoAP carries the same four REST verbs as HTTP: GET, POST, PUT, and DELETE.
  • GET, PUT, and DELETE are idempotent; POST is not, so duplicate delivery must be considered.
  • A thermostat API should read with GET, update with PUT, and reserve POST for one-time actions.

8.6 Code Examples

8.6.1 Python CoAP Server

import asyncio
from aiocoap import *

class TemperatureResource(resource.Resource):
    """Example resource for temperature readings"""

    async def render_get(self, request):
        """Handle GET requests"""
        temperature = 22.5  # Simulated sensor reading

        payload = f"{temperature}".encode('utf-8')

        return Message(
            code=Code.CONTENT,
            payload=payload,
            content_format=0  # text/plain
        )

    async def render_put(self, request):
        """Handle PUT requests to update config"""
        print(f'Received: {request.payload}')

        return Message(code=Code.CHANGED)

async def main():
    # Create CoAP server
    root = resource.Site()

    # Add temperature resource
    root.add_resource(
        ['temperature'],
        TemperatureResource()
    )

    # Start server
    await Context.create_server_context(root)

    print("CoAP server started on port 5683")
    await asyncio.get_running_loop().create_future()

if __name__ == "__main__":
    asyncio.run(main())

Install: pip install aiocoap

8.6.2 Python CoAP Client

import asyncio
from aiocoap import *

async def get_temperature():
    """Fetch temperature from CoAP server"""

    # Create CoAP client protocol
    protocol = await Context.create_client_context()

    # Build GET request
    request = Message(
        code=Code.GET,
        uri='coap://localhost/temperature'
    )

    try:
        # Send request
        response = await protocol.request(request).response

        print(f'Response Code: {response.code}')
        print(f'Temperature: {response.payload.decode("utf-8")}°C')

    except Exception as e:
        print(f'Failed to fetch: {e}')

async def update_config():
    """Send PUT request to update configuration"""

    protocol = await Context.create_client_context()

    request = Message(
        code=Code.PUT,
        uri='coap://localhost/config',
        payload=b'{"interval": 30}'
    )

    response = await protocol.request(request).response
    print(f'Update result: {response.code}')

# Run client
asyncio.run(get_temperature())

8.6.3 Arduino ESP32 CoAP Client

#include <WiFi.h>
#include <coap-simple.h>

// WiFi credentials
const char* ssid = "YourWiFi";
const char* password = "YourPassword";

// CoAP client
Coap coap;

// CoAP server details
IPAddress serverIP(192, 168, 1, 100);
int serverPort = 5683;

void callback_response(CoapPacket &packet, IPAddress ip, int port) {
  char payload[packet.payloadlen + 1];
  memcpy(payload, packet.payload, packet.payloadlen);
  payload[packet.payloadlen] = NULL;

  Serial.print("CoAP Response: ");
  Serial.println(payload);
}

void setup() {
  Serial.begin(115200);

  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi connected");

  // Start CoAP
  coap.response(callback_response);
  coap.start();
}

void loop() {
  // Send GET request every 10 seconds
  int msgid = coap.get(serverIP, serverPort, "temperature");

  Serial.print("Request sent, MID: ");
  Serial.println(msgid);

  delay(10000);

  coap.loop();
}

8.7 Interactive Comparison: CoAP vs MQTT vs HTTP

Interactive element unavailable — chart cell

Plot: Observable Plot (charting library) is not bundled

Show source

Plot.plot({
marks: [
Plot.barY(protocolData, {
x: "protocol",
y: "value",
fill: d => d.protocol === "CoAP" ? colors.teal :
d.protocol === "MQTT" ? colors.orange : colors.navy,
tip: true
}),
Plot.text(protocolData, {
x: "protocol",
y: "value",
text: d => `${d.value} ${d.unit}`,
dy: -10,
fill: colors.navy,
fontSize: 12
})
],
x: {label: "Protocol"},
y: {label: protocolMetric, grid: true},
marginTop: 20,
marginBottom: 40,
height: 300,
style: {
fontFamily: "Arial, sans-serif"
}
})
Key Insights

CoAP Advantages:

  • ✓ Smallest header size (4 bytes) - minimal overhead
  • ✓ Best battery life (UDP, no connection overhead)
  • ✓ RESTful design - familiar to web developers
  • ✓ Low latency - simple request/response

When CoAP Wins:

  • Resource-constrained devices (8-bit microcontrollers)
  • Battery-powered sensors (years not months)
  • Intermittent connectivity (devices sleep often)
  • Integration with web infrastructure (HTTP proxies)

When to Choose Alternatives:

  • MQTT: Publish-subscribe needed, TCP reliability required
  • HTTP: Full web stack needed, rich tooling ecosystem

The simulator comparisons become a protocol choice only after interaction pattern and device constraints are considered together. Use Figure 8.1 to turn those observations into a repeatable selection route.

Decision tree for IoT protocol selection: choose CoAP for small REST operations on named resources, sleeping sensors, UDP, and 4-byte headers; choose MQTT when brokered publish-subscribe fan-out and QoS are needed; choose HTTP when a full web API stack, tooling, and proxy integration outweigh higher setup and header cost.
Figure 8.1: Protocol selection decision tree for choosing CoAP, MQTT, or HTTP from interaction pattern and device constraints.

Read Figure 8.1 from the interaction question at the top. Small operations on named resources lead toward CoAP when sleep cycles, UDP, and tight headers matter; brokered fan-out leads toward MQTT; a full web API and proxy ecosystem leads toward HTTP. The branches describe fit, not a universal winner. Having chosen an interaction model, the next question is what that choice costs on the wire.

8.8 Interactive Tool: CoAP Message Size Calculator

Calculate the actual bytes sent over the network for different protocols:

Interactive element unavailable — chart cell

Plot: Observable Plot (charting library) is not bundled

Show source

Plot.plot({
marks: [
Plot.barX([
{protocol: "CoAP", size: messageSizes.coap, color: colors.teal},
{protocol: "MQTT", size: messageSizes.mqtt, color: colors.orange},
{protocol: "HTTP", size: messageSizes.http, color: colors.navy}
], {
y: "protocol",
x: "size",
fill: "color",
tip: true
}),
Plot.text([
{protocol: "CoAP", size: messageSizes.coap},
{protocol: "MQTT", size: messageSizes.mqtt},
{protocol: "HTTP", size: messageSizes.http}
], {
y: "protocol",
x: "size",
text: d => `${d.size} bytes`,
dx: 20,
fill: colors.navy,
fontSize: 12
})
],
x: {label: "Total Message Size (bytes)", grid: true},
y: {label: null},
marginLeft: 80,
marginRight: 100,
height: 200,
style: {
fontFamily: "Arial, sans-serif"
}
})
Message Size Optimization

For small payloads (< 100 bytes), protocol overhead dominates. Try adjusting the payload size above to see how CoAP’s efficiency scales.

Recommendation: For sensors sending small readings frequently, CoAP’s low overhead translates to:

  • Reduced network congestion
  • Longer battery life (less radio time)
  • Lower latency (smaller packets = faster transmission)

8.9 Battery Life Calculator: CON vs NON Messages

Delivery policy changes radio work, so use the interactive battery-life calculator below before treating CON or NON as a default. Set the daily message rate first, then switch message type and compare size, daily energy, and the modeled battery-life bars.

Interactive element unavailable — chart cell

Plot: Observable Plot (charting library) is not bundled

Show source

Plot.plot({
marks: [
Plot.barY(comparisonData, {
x: "type",
y: "years",
fill: d => d.type === "NON" ? colors.teal : colors.orange,
tip: true
}),
Plot.text(comparisonData, {
x: "type",
y: "years",
text: d => `${d.years} years`,
dy: -10,
fill: colors.navy,
fontSize: 12
})
],
x: {label: "Message Type"},
y: {label: "Battery Life (years)", grid: true},
marginTop: 20,
marginBottom: 40,
height: 300,
style: {
fontFamily: "Arial, sans-serif"
}
})

In the interactive calculator, the daily rate controls how often the radio pays the transaction cost, while the message-type selector adds the ACK bytes used by this simplified CON model. Read the numeric cards before the bars: message size drives energy per day, which drives the projected years. The result isolates message traffic and therefore supports a relative CON-versus-NON decision; it is not a complete product battery forecast.

Critical Battery Life Insights

NON vs CON Performance:

Read these points as one connected sequence: start with NON messages skip acknowledgment, saving approximately 21% energy per transaction (45 bytes vs 57 bytes for CON + ACK round-trip); then CON messages require an ACK response, adding 12 bytes of overhead and an additional receive window — increasing per-message energy by ~27% compared to NON; then For sensors with reliable links, NON can extend battery life by years; and finish with Use CON only when guaranteed delivery is critical.

  • NON messages skip acknowledgment, saving approximately 21% energy per transaction (45 bytes vs 57 bytes for CON + ACK round-trip)
  • CON messages require an ACK response, adding 12 bytes of overhead and an additional receive window — increasing per-message energy by ~27% compared to NON
  • For sensors with reliable links, NON can extend battery life by years
  • Use CON only when guaranteed delivery is critical

Broker BexCheckpoint: Message Cost

You now know:

  • CoAP’s base header is 4 bytes; the HTTP comparison uses 100-200 bytes of headers plus setup.
  • For the 5-byte temperature example, the chapter’s model gives 45 bytes for CoAP and 425 bytes for HTTP.
  • CON adds a 12-byte ACK path over the NON case, so reliability has a measurable battery cost.

Interactive Simulator: CoAP-Style UDP Communication

What This Simulates: ESP32 demonstrating CoAP’s lightweight UDP request/response pattern

Before starting the simulator, inspect Figure 8.2 to predict which endpoint owns each resource and which identifiers should match when the response returns.

CoAP UDP request and response diagram: an ESP32 client sends GET and PUT datagrams to a sensor server on UDP 5683, the server maps methods to /temperature and /led resources, and message IDs plus tokens match ACK or content responses without a TCP handshake.
Figure 8.2: CoAP UDP request/response pattern between an ESP32 client and a resource-oriented sensor server.

Read the diagram in Figure 8.2 from the ESP32 client across UDP port 5683 to the sensor server. GET selects /temperature, while PUT targets /led; the server maps each method and path to resource behavior. On the return path, Message IDs support the exchange and Tokens correlate responses with requests. Use those predicted fields as checkpoints while the serial trace runs.

How to Use:

  1. Select Start Simulation
  2. Watch Serial Monitor show UDP request/response cycle
  3. Observe message types (CON, NON, ACK)
  4. See CoAP-style resource addressing
  5. Monitor round-trip times (RTT)

Learning Points

Read the simulator trace as one story before using the lists as a recap. Begin with the UDP datagram leaving without a TCP handshake, locate the compact CoAP header, then match the REST request to its response using the Message ID and Token. That order connects transport economy to application behavior: fewer setup exchanges save airtime, while resource paths and methods still give the device a clear interface. After the trace works, vary one factor at a time—request frequency, resource count, Observe behavior, or CON delivery—and explain the resulting traffic rather than treating the defaults as universal.

What You’ll Observe:

  1. UDP Transport - Connectionless, lightweight communication
  2. 4-Byte Headers - Minimal overhead compared to HTTP
  3. Request/Response - RESTful pattern like HTTP GET
  4. Message IDs - Tracking requests and responses
  5. No Handshake - Direct communication without TCP overhead

CoAP Message Structure (Simplified):

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T |  TKL  |      Code     |          Message ID           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Ver = Version (2 bits)
T   = Type (CON, NON, ACK, RST)
TKL = Token Length
Code = Method (GET) or Response (2.05 Content)

Real-World Applications:

  1. Smart Home - Light bulbs responding to GET/PUT requests
  2. Industrial IoT - Sensors publishing data via RESTful interface
  3. Building Automation - HVAC systems with RESTful control
  4. Energy Management - Smart meters with resource discovery
  5. Wearables - Health sensors with minimal power consumption

Experiments to Try:

  1. Change Request Frequency - Modify delay() to see network load
  2. Add More Resources - Simulate /humidity, /pressure endpoints
  3. Implement Observe - Add subscription pattern (like MQTT subscribe)
  4. Calculate Overhead - Compare 4-byte CoAP vs HTTP headers
  5. Test Reliability - Implement CON (confirmable) message handling

CoAP vs HTTP Power Consumption:

HTTP Request:  ~500 bytes (headers + TCP)
CoAP Request:  ~20 bytes (4-byte header + minimal payload)
Power Savings: ~96% less data transmitted

8.10 Multicast Support

Once a single exchange is clear, scale the same resource model to a group. Multicast helps discovery without changing what GET means.

CoAP supports multicast for group communication:

8.10.1 IPv4 Multicast

224.0.1.187

8.10.2 IPv6 Multicast

FF0X::FD

Use cases:

  • Discover devices on network
  • Broadcast commands to group
  • Query multiple sensors simultaneously

Example:

coap://[FF05::FD]/temperature

Sends GET request to all devices in multicast group.

8.10.3 Multicast Efficiency Calculator

Use the calculator to compare request amplification, not to assume multicast makes every operation safe. Set Number of Devices first, then switch Communication Type between Unicast (individual) and Multicast (group). Unicast increases request count and sequential time with every device; multicast holds the outbound request count at one but still receives one response per participating endpoint. That distinction explains why discovery benefits from multicast while state-changing commands still need per-device authorization, outcome tracking, and retry decisions.

Interactive element unavailable — chart cell

Plot: Observable Plot (charting library) is not bundled

Show source

Plot.plot({
marks: [
Plot.barY(compData, {
x: "method",
y: "bytes",
fill: d => d.method === "Multicast" ? colors.teal : colors.navy,
tip: true
}),
Plot.text(compData, {
x: "method",
y: "bytes",
text: d => `${d.bytes} bytes`,
dy: -10,
fill: colors.navy,
fontSize: 12
})
],
x: {label: "Communication Method"},
y: {label: "Total Bandwidth (bytes)", grid: true},
marginTop: 20,
marginBottom: 40,
height: 300,
style: {
fontFamily: "Arial, sans-serif"
}
})

Broker BexCheckpoint: Discovery and Observe

You now know:

  • Multicast can send one discovery request instead of contacting 50 sensors one by one.
  • Polling 50 sensors every 5 seconds creates 600 request cycles per minute even when values stay stable.
  • Observe fixes the polling problem by registering once and sending updates only when the resource changes.

8.11 CoAP Features

Key Features

Read these points as one connected sequence: start with Reduced Overhead: 4-byte header vs 100+ bytes in HTTP; then URI Support: Resource addressing like HTTP; then Content-Type: Supports JSON, XML, CBOR, etc; then Resource Discovery: Automatic service discovery (/.well-known/core); then Observe Pattern: Subscribe to resources, receive push notifications; then Simple Caching: Based on maximum message age; then Block-wise Transfer: For large payloads; and finish with Security: DTLS encryption.

  1. Reduced Overhead: 4-byte header vs 100+ bytes in HTTP
  2. URI Support: Resource addressing like HTTP
  3. Content-Type: Supports JSON, XML, CBOR, etc.
  4. Resource Discovery: Automatic service discovery (/.well-known/core)
  5. Observe Pattern: Subscribe to resources, receive push notifications
  6. Simple Caching: Based on maximum message age
  7. Block-wise Transfer: For large payloads
  8. Security: DTLS encryption

8.11.1 Resource Discovery

Query available resources:

GET coap://device.local/.well-known/core

Response:

</temperature>;ct=0,
</humidity>;ct=0,
</pressure>;ct=0,
</config>;ct=50
Interactive Simulator: CoAP Resource Discovery

What This Simulates: ESP32 CoAP server with automatic resource discovery via /.well-known/core

Resource Discovery Flow:

Step 1: Client queries server
   GET coap://device/.well-known/core

Step 2: Server responds with resource list
   </temperature>;rt="sensor";if="core.s",
   </humidity>;rt="sensor";if="core.s",
   </led>;rt="actuator";if="core.a"

Step 3: Client accesses specific resource
   GET coap://device/temperature
   Response: "23.5"

How to Use:

  1. Select Start Simulation
  2. Watch ESP32 advertise available resources
  3. See resource metadata (resource type, interface)
  4. Observe clients discovering services automatically
  5. Monitor GET requests to discovered resources

Learning Points

Treat discovery as a negotiation, not merely a directory listing. First request /.well-known/core, then parse each link into its resource path and attributes. The resource type says what the endpoint represents, the interface says how a client should interact with it, content format says what representation to expect, and obs advertises notification support. Only after those claims are understood should the client issue a request. The experiments below summarize ways to change that contract; each change should be checked in both the advertisement and the behavior of the discovered resource.

What You’ll Observe:

  1. Automatic Discovery - Devices announce capabilities without manual configuration
  2. Standard Endpoint - /.well-known/core is CoAP convention (RFC 6690)
  3. Resource Attributes - Metadata describes resource type and interface
  4. Self-Describing - Servers advertise what they offer
  5. Plug-and-Play - New devices integrate without central registry

Resource Link Format:

</path>;attribute1=value1;attribute2=value2

Common Attributes:
rt = Resource Type (e.g., "temperature-sensor")
if = Interface Description (e.g., "sensor", "actuator")
ct = Content Type (0=text/plain, 50=application/json)
sz = Maximum Size
obs = Observable (supports observe pattern)

Example Resource Advertisement:

Resource discovery is useful only if a client can interpret an advertisement rather than merely find a URI. Inspect Figure 8.3 to decode the example from the path outward through its link-format attributes.

CoAP resource link format example showing a slash-temp path, resource type temperature-sensor, interface sensor, content type zero for text/plain, and obs indicating Observe support.
Figure 8.3: CoAP resource link format field breakdown for a temperature sensor advertisement.

In Figure 8.3, start with /temp, the resource a client can request. Then read rt as its semantic resource type, if as the interaction interface, ct=0 as the representation’s content-format, and obs as the promise that Observe registration is supported. Those attributes let discovery feed a compatible client action, which is why the application examples below can find capabilities without hard-coded endpoint catalogs.

Real-World Applications:

  1. Smart Building - HVAC units discover sensors automatically
  2. Industrial IoT - Factory machines advertise capabilities
  3. Home Automation - New devices self-register with hub
  4. Healthcare - Medical sensors announce monitoring types
  5. Agriculture - Soil sensors advertise measurement types

Experiments to Try:

  1. Add New Resources - Implement /pressure, /battery endpoints
  2. Resource Attributes - Add obs for observable resources
  3. Content Types - Support JSON (ct=50) and XML (ct=41)
  4. Filtering - Query specific resource types: ?rt=sensor
  5. Observe Pattern - Implement push notifications when resource changes

Discovery vs Hardcoding:

Without Discovery (Hardcoded):
- Client: GET coap://192.168.1.100/temp  ✗ Must know IP & path
- Brittle: Breaks if device IP changes

With Discovery:
- Client: Multicast GET /.well-known/core  ✓ Finds all devices
- Response: Server at 192.168.1.100 offers /temp
- Robust: Adapts to network changes

CoAP Resource Discovery Benefits:

  • Zero configuration networking
  • Dynamic topology adaptation
  • Service versioning support
  • Reduces integration time by ~80%
Knowledge Check: Match and Sequence

Match each CoAP concept to its correct definition or use case:

Arrange the following steps of a CoAP resource discovery and subscription workflow in the correct order:

8.12 Protocol Comparison

The feature tour is complete: methods name the operation, discovery finds resources, and Observe changes polling into push. Now compare CoAP with HTTP and MQTT.

8.12.1 CoAP vs HTTP: Concrete Performance Numbers

FeatureCoAPHTTPCoAP Advantage
TransportUDPTCPNo handshake overhead
Header Size4 bytes100-200 bytes96% reduction
Total On-Wire Size40-60 bytes250-600 bytes85-93% smaller
Connection SetupNone (UDP)3-way handshakeSaves 1+ RTT + ~180 bytes
MethodsGET, POST, PUT, DELETESame + moreFocused on IoT needs
DiscoveryBuilt-in (/.well-known/core)No standardZero-config networking
MulticastYes (FF0X::FD)NoOne-to-many efficiency
ObserveYes (push notifications)Server-Sent Events99% less polling traffic
SecurityDTLSTLSUDP-optimized
Power per Message3-5 mJ30-50 mJ10x more efficient
Battery Life Impact2-5 years2-6 months10x longer life

Real Numbers Example - Temperature Reading:

Scenario: Send “22.5C” (5 bytes payload) from sensor to server

8.12.1.1 Putting Numbers to It

Total message overhead directly affects both bandwidth and battery life. For payload PP bytes:

Btotal=Hprotocol+Htransport+PB_{\text{total}} = H_{\text{protocol}} + H_{\text{transport}} + P

CoAP message: Bc=4 (header)+8 (token+options)+28 (UDP/IP)+5 (payload)=45B_c = 4\text{ (header)} + 8\text{ (token+options)} + 28\text{ (UDP/IP)} + 5\text{ (payload)} = 45 bytes

HTTP message: Bh=200 (headers)+40 (TCP/IP)+5 (payload)+180 (handshake)=425B_h = 200\text{ (headers)} + 40\text{ (TCP/IP)} + 5\text{ (payload)} + 180\text{ (handshake)} = 425 bytes

For 1,000 daily readings at 3V, 200mA peak transmit current (typical for an ESP32 Wi-Fi radio), 250kbps effective link rate: Ec=1000×45×8250,000×0.2A×3V=0.86 J/dayE_c = 1000 \times \frac{45 \times 8}{250,000} \times 0.2\text{A} \times 3\text{V} = 0.86\text{ J/day}

Eh=1000×425×8250,000×0.2A×3V=8.16 J/dayE_h = 1000 \times \frac{425 \times 8}{250,000} \times 0.2\text{A} \times 3\text{V} = 8.16\text{ J/day}

With CR2032 battery (675 mWh = 2,430 J): CoAP enables 7.7 years vs HTTP’s 0.8 years of TX-only battery life. The 9.4× overhead ratio translates directly to a 9.4× difference in radio energy per day. Note: real-world battery life will be shorter due to sleep/idle current, MCU processing, and other loads; this model isolates the protocol overhead contribution.

The arithmetic above becomes easier to audit when bytes, energy, and lifetime stay on one scale. Use Figure 8.4 to check that each stage preserves the same overhead ratio.

Comparison chart for the chapter model: CoAP uses 45 bytes and 0.86 joules per day for one thousand daily readings, while HTTP uses 425 bytes and 8.16 joules per day, yielding 7.7 versus 0.8 years of TX-only CR2032 battery life.
Figure 8.4: CoAP versus HTTP overhead for a 5-byte temperature reading, comparing total on-wire bytes, daily radio energy, and TX-only CR2032 battery life.

Read Figure 8.4 from on-wire bytes to daily energy and finally to TX-only battery life. The example’s 45-versus-425-byte traffic becomes 0.86 versus 8.16 joules per day under the same radio assumptions, so the lifetime bars reverse in length. Because sleep current, computation, retries, and battery behavior are excluded, carry forward the comparative conclusion—protocol overhead matters—not the projected years as a deployment promise.

Broker BexCheckpoint: Protocol Selection

You now know:

  • CoAP keeps REST-style GET, POST, PUT, and DELETE while avoiding TCP setup.
  • In the chapter model, 1,000 daily readings produce 0.86 J/day for CoAP and 8.16 J/day for HTTP radio transmission.
  • The isolated protocol-overhead model yields 7.7 years versus 0.8 years of TX-only battery life before other loads are counted.

8.12.2 CoAP vs MQTT

FeatureCoAPMQTT
PatternRequest/ResponsePublish/Subscribe
TransportUDPTCP
DiscoveryBuilt-inExternal
QoSVia message type3 levels (0,1,2)
BrokerOptionalRequired
Best ForRESTful IoTEvent-driven IoT
Label the Diagram

8.13 CON and NON Pattern Evidence

Choose the CoAP message type per interaction, not per deployment. The method tells the server what operation to perform; CON or NON tells the protocol how much delivery evidence is worth paying for.

InteractionPreferReason
Periodic temperature or humidity readingNONThe next reading replaces the missing one, so avoiding ACK traffic usually matters more than perfect delivery
User-initiated configuration PUTCONThe user or controller needs acknowledgement that the new state was accepted
Door unlock, alarm, valve close, or safety threshold alertCONSilent loss creates a safety or security failure
High-frequency heartbeatNON, with application-level missing-heartbeat detectionMissing one heartbeat is tolerable; several missing heartbeats become the signal
Firmware block transferCONEvery block must arrive or be retried to reconstruct the payload

For constrained sensors, a hybrid policy is often the measurable answer: routine telemetry as NON, rare commands and critical alerts as CON. Record the tolerated loss rate, expected message frequency, and retry budget so the battery and reliability tradeoff can be checked in tests.

8.14 See Also

Read these points as one connected sequence: start with CoAP Method Codes and Multicast Contracts: Deepen method-code, response-code, retry, multicast, Token, and Leisure behavior; then CoAP Message Types: Review how CON, NON, ACK, and RST messages support method exchanges; then CoAP Observe Extension: Extend GET semantics into server-pushed resource updates; then CoAP Advanced Features: Continue from core methods into block-wise transfer, proxies, and advanced constrained workflows; and finish with CoAP vs MQTT and Use Cases: Compare REST-style CoAP methods with brokered MQTT publish/subscribe.

8.15 Summary

CoAP methods and features work together: methods define the resource operation, content format defines representation, Observe reduces polling, and block-wise transfer handles payloads that do not fit in one datagram.

8.16 Key Takeaway

Keep CoAP designs resource-centered. If the interaction cannot be described as a small operation on a named resource, MQTT, HTTP, or a gateway pattern may be a better fit.