%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#E8F4F8','primaryTextColor':'#2C3E50','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#FEF5E7'}}}%%
flowchart LR
subgraph CON["Confirmable (CON)"]
C1[Client] -->|"GET /temp"| C2[Server]
C2 -->|"ACK + 2.05"| C1
end
subgraph NON["Non-Confirmable (NON)"]
N1[Client] -->|"POST /reading"| N2[Server]
end
subgraph OBS["Observe Pattern"]
O1[Client] -->|"GET + Observe"| O2[Server]
O2 -->|"Notify 1"| O1
O2 -->|"Notify 2"| O1
O2 -->|"Notify N"| O1
end
style CON fill:#E8F4F8,stroke:#16A085
style NON fill:#FEF5E7,stroke:#E67E22
style OBS fill:#E8F8F5,stroke:#16A085
1229 CoAP Methods and Communication Patterns
1229.1 Learning Objectives
By the end of this chapter, you will be able to:
- Apply CoAP Methods: Use GET, POST, PUT, DELETE for RESTful IoT communication
- Choose Message Types: Select between Confirmable (CON) and Non-Confirmable (NON) based on reliability requirements
- Compare Polling vs Observe: Evaluate bandwidth and power tradeoffs for monitoring scenarios
- Calculate Bandwidth Savings: Quantify Observe pattern efficiency for specific deployments
- Avoid Common Misconceptions: Understand how CoAP differs from HTTP despite RESTful similarities
1229.2 Prerequisites
Before diving into this chapter, you should be familiar with:
- CoAP Fundamentals and Architecture: Understanding of CoAP’s core design, message types (CON, NON, ACK, RST), and how it differs from HTTP is essential
- IoT Protocols Fundamentals: Knowledge of the protocol stack, UDP transport, and RESTful principles
- Networking Basics: Familiarity with client-server architecture and request-response patterns
Core CoAP Knowledge: - CoAP Overview - Protocol fundamentals and concepts - CoAP Architecture - Message types and protocol design - CoAP Implementation Labs - Hands-on code examples - CoAP Advanced Features Lab - ESP32 Wokwi simulation
Compare with Other Protocols: - MQTT Labs - Hands-on MQTT implementations - IoT Protocols Overview - Protocol selection guidance - Application Protocols - Full protocol comparison
Production Deployment: - Edge Computing - CoAP in edge architectures - Security Methods - DTLS and security
CoAP (Constrained Application Protocol) uses a RESTful approach similar to HTTP but optimized for constrained devices. This chapter focuses on how to communicate using CoAP.
Key concepts:
| Term | Simple Explanation |
|---|---|
| Method | The action you want (GET=read, PUT=update, POST=create, DELETE=remove) |
| CON | Confirmable message - “I need to know you received this” |
| NON | Non-Confirmable message - “Fire and forget, no reply needed” |
| Observe | Subscribe to updates - “Tell me when this changes” |
| Polling | Repeatedly asking - “Has it changed yet? How about now?” |
Think of CON vs NON like sending a letter (CON = registered mail with tracking, NON = regular mail).
1229.3 Common Misconception: “CoAP is just HTTP over UDP”
The Misconception: Many assume CoAP is simply HTTP with UDP transport, leading to incorrect assumptions about message reliability, header structure, and behavior.
Why This Is Wrong:
1. Message Types Are Different: - HTTP: Only request/response (no built-in message acknowledgment) - CoAP: Four message types - CON (confirmable, requires ACK), NON (non-confirmable), ACK (acknowledgment), RST (reset) - Impact: CoAP provides optional reliability at the application layer, not transport layer
2. Header Overhead Drastically Different: - HTTP/1.1 GET: Typically 200-500 bytes (text headers: “GET /temp HTTP/1.1: sensor.local-Agent:…”) - CoAP GET: 4-byte fixed header + token + options (total ~10-20 bytes) - Quantified: 90-95% smaller headers - Critical for battery-powered sensors sending thousands of messages
3. Observe Pattern Has No HTTP Equivalent: - HTTP: Client must poll repeatedly (GET /temp every 10s = wasted bandwidth even when no change) - CoAP Observe: Client sends GET /temp with Observe option (1 byte), server sends updates ONLY when value changes - Impact: In a deployment with 1000 sensors polling every 10s: - HTTP polling: 1000 requests/10s = 100 req/s continuously, even if temperature unchanged - CoAP observe: 1 request per sensor, then only updates on change (e.g., 5 notifications/hour if temperature stable) - Bandwidth saved: 99%+ in stable monitoring scenarios
4. Block Transfer Is Not HTTP Chunked Encoding: - HTTP chunked: Server controls chunking, client receives stream - CoAP block: Client can request specific blocks (e.g., “send me blocks 0-10”), supports retry of individual blocks - Use case: Firmware update interrupted? CoAP resumes from block 47, HTTP restarts entire download
Real-World Example: A smart agriculture deployment monitors 500 soil sensors: - Incorrect HTTP-over-UDP approach: Every sensor polls server every 30s -> 500 x 200 bytes x 2 (req+resp) x 2880 times/day = 576 MB/day - CoAP observe: 500 sensors register once (10 KB total), then 50 notifications/day when moisture changes -> 50 x 20 bytes x 500 = 0.5 MB/day - Result: 99.9% bandwidth reduction by using CoAP correctly, not treating it like HTTP
1229.4 CoAP Methods
Like HTTP, CoAP uses REST methods for resource manipulation:
| Method | Purpose | HTTP Equivalent | Idempotent |
|---|---|---|---|
| GET | Retrieve resource | GET | Yes |
| POST | Create resource | POST | No |
| PUT | Update/Create | PUT | Yes |
| DELETE | Remove resource | DELETE | Yes |
1229.4.1 Method Examples
GET: Retrieve temperature reading
coap://sensor.local/temperature
POST: Add new sensor reading (creates new resource)
coap://server.local/readings
Payload: {"temp": 23.5, "time": "2025-10-24T23:30:00Z"}
PUT: Update device configuration (idempotent - same result if repeated)
coap://device.local/config
Payload: {"interval": 60}
DELETE: Remove old data
coap://server.local/readings/old
Idempotent means repeating the operation produces the same result. This is crucial for unreliable networks:
- GET, PUT, DELETE: Safe to retry on timeout (same result)
- POST: NOT safe to retry blindly (may create duplicates)
For POST operations on unreliable links, use a token or check-before-create pattern to avoid duplicates.
1229.5 Tradeoff: Confirmable (CON) vs Non-Confirmable (NON)
Option A: Use Confirmable (CON) messages - requires ACK from receiver, automatic retransmission on timeout
Option B: Use Non-Confirmable (NON) messages - fire-and-forget, no acknowledgment, no retries
Decision Factors:
| Factor | Confirmable (CON) | Non-Confirmable (NON) |
|---|---|---|
| Reliability | Guaranteed delivery (with retries) | Best-effort (may be lost) |
| Latency (success) | RTT + processing (50-200ms typical) | One-way (<50ms typical) |
| Latency (failure) | Retry timeout x max retries (2-60 seconds) | N/A (no retry) |
| Power consumption | 2-10x higher (ACK wait, retries) | Minimal (single transmission) |
| Bandwidth | 2x per message (request + ACK) | 1x (request only) |
| Network congestion | Higher (ACK traffic + retries) | Lower |
| Implementation | Complex (timeout tracking, retry queue) | Simple (send and forget) |
| Loss detection | Immediate (ACK timeout) | None (silent failure) |
Choose Confirmable (CON) when: - Actuator commands that must execute (valve open, door unlock, motor start) - Configuration changes that must be acknowledged - Alert/alarm notifications where silence is dangerous - Firmware update packets that cannot be skipped - Infrequent but critical messages (1 message/minute or less) - Example: Smart lock PUT /lock/state {"locked": false} - must confirm door unlocked
Choose Non-Confirmable (NON) when: - High-frequency telemetry where next reading replaces missed one - Battery-constrained sensors (each ACK doubles energy per message) - Real-time streaming where retries cause stale data - Multicast messages (cannot ACK multicast) - Lossy networks where retries cause congestion collapse - Example: Temperature sensor POST /readings {"temp": 22.5} every 10 seconds - missing one reading is acceptable
Real-world example: Smart agriculture irrigation system: - Soil moisture readings (every 30 min): Use NON - 48 readings/day x 500 sensors = 24,000 messages - NON: 24,000 transmissions, ~0.5mAh per sensor per day - CON: 48,000 transmissions (with ACKs), ~1.0mAh per sensor per day - Battery life: NON = 5 years, CON = 2.5 years - Irrigation valve commands (5 per day): Use CON - 5 commands x 500 valves = 2,500 messages - CON overhead negligible (10 transmissions per valve per day) - Missed valve command = crop damage worth $1000+ - ROI: $0.10 extra battery cost vs $1000 crop loss risk
1229.6 Tradeoff: Polling vs Observe Pattern
Option A: Use polling - client sends periodic GET requests to check resource state
Option B: Use Observe pattern - client registers once, server pushes updates only when value changes
Decision Factors:
| Factor | Polling | Observe |
|---|---|---|
| Initial setup | None (just GET) | Register with Observe option |
| Message count (stable data) | High (every poll interval) | Low (only on changes) |
| Message count (volatile data) | Same as observe | High (every change notification) |
| Latency to detect change | Poll interval / 2 average | Near-instantaneous |
| Client complexity | Simple (timer + GET) | Moderate (subscription management) |
| Server complexity | Stateless | Stateful (track observers) |
| Server memory | None per client | ~50-100 bytes per observer |
| NAT/firewall handling | Client-initiated (NAT-friendly) | Server-initiated (may need keep-alive) |
| Lost notification recovery | Next poll catches up | Client must re-register |
Choose Polling when: - Data changes frequently (>1 change per poll interval makes observe inefficient) - Client cannot maintain long-lived state (stateless microservices) - NAT/firewall prevents server-initiated connections - Simplicity is priority (no observer lifecycle management) - Acceptable latency = seconds to minutes - Example: Dashboard checking 100 devices every 60 seconds - predictable load pattern
Choose Observe when: - Data changes infrequently relative to monitoring frequency - Real-time notification required (<1 second latency) - Bandwidth/battery critical (agricultural sensors checking hourly but only irrigating daily) - Event-driven architecture (actuator waiting for command) - Sensor -> gateway communication on local network (no NAT issues) - Example: Door sensor reporting open/close events - may be hours between changes
Real-world example: Smart building HVAC monitoring with 200 temperature sensors:
Scenario A: Polling every 10 seconds (traditional approach) - Messages: 200 sensors x 6 requests/minute x 60 minutes = 72,000 msg/hour - Each request: 20 bytes (GET /temp) + 20 bytes (response) = 40 bytes - Bandwidth: 72,000 x 40 = 2.88 MB/hour - Battery: ~2.5mAh/hour per sensor (constant wake cycles)
Scenario B: Observe pattern (smart approach) - Temperature stable (changes <0.5C): ~2 notifications/hour per sensor - Temperature volatile (HVAC cycling): ~20 notifications/hour per sensor - Average: 10 notifications/hour per sensor - Messages: 200 sensors x 10 = 2,000 msg/hour (97% reduction!) - Bandwidth: 2,000 x 20 bytes = 40 KB/hour (99% reduction!) - Battery: ~0.1mAh/hour per sensor (sleep between notifications) - Battery life improvement: 25x longer
Hybrid approach: Use observe for real-time display, poll every 5 minutes as backup to catch missed notifications or re-establish broken observations.
1229.7 Worked Example: Observe Bandwidth Savings
Scenario: A smart building deployment monitors 500 temperature sensors. Management wants to compare the network cost of traditional polling versus CoAP Observe for a 24-hour period.
Given: - Number of sensors: 500 - Polling interval (if used): 30 seconds - Average temperature changes per sensor per hour: 4 (HVAC cycles) - CoAP GET request size: 18 bytes (4B header + 2B token + 12B options) - CoAP response size: 24 bytes (4B header + 2B token + 6B options + 12B JSON payload) - Observe notification size: 26 bytes (adds 2B observe sequence number)
Steps:
- Calculate polling traffic (traditional approach):
- Polls per sensor per day = (24 hours x 60 min x 60 sec) / 30 sec = 2,880 polls
- Bytes per poll = 18 (request) + 24 (response) = 42 bytes
- Total per sensor = 2,880 x 42 = 120,960 bytes/day
- Total for 500 sensors = 500 x 120,960 = 60,480,000 bytes/day (57.7 MB)
- Calculate Observe traffic (CoAP approach):
- Registration per sensor = 18 (GET with Observe:0) + 26 (initial response) = 44 bytes
- Changes per sensor per day = 4 changes/hour x 24 hours = 96 notifications
- Notification bytes per sensor = 96 x 26 = 2,496 bytes/day
- Total per sensor = 44 + 2,496 = 2,540 bytes/day
- Total for 500 sensors = 500 x 2,540 = 1,270,000 bytes/day (1.21 MB)
- Calculate bandwidth savings:
- Reduction = (60,480,000 - 1,270,000) / 60,480,000 = 97.9% savings
- Absolute savings = 60,480,000 - 1,270,000 = 59.21 MB/day
- Estimate power impact (assuming 20 mA transmit, 200 ms per message):
- Polling: 2,880 messages x 500 sensors x 0.2 sec x 20 mA = 5,760 Ah/day
- Observe: (1 + 96) x 500 sensors x 0.2 sec x 20 mA = 194 Ah/day
- Power reduction: 96.6%
Result: CoAP Observe reduces network traffic from 57.7 MB/day to 1.21 MB/day (97.9% reduction) and power consumption by 96.6%. The building’s IoT gateway bandwidth requirements drop from 5.3 Mbps peak to 0.11 Mbps.
Key Insight: Observe pattern efficiency scales with the ratio of monitoring frequency to actual data changes. For slowly-changing data (temperature, humidity) with high monitoring frequency, savings exceed 95%. For rapidly-changing data (vibration sensors, power meters), polling may be more appropriate as notifications would approach polling frequency anyway.
1229.8 Common Pitfall: Using CON for High-Frequency Telemetry
The Mistake: Configuring all sensor readings to use CON (Confirmable) messages because “reliability is important,” causing a soil moisture sensor network to drain batteries in 6 months instead of the designed 5-year lifespan.
Why It Happens: Developers confuse “data importance” with “delivery confirmation need.” CON messages require acknowledgment within 2-second ACK_TIMEOUT, triggering up to 4 retransmissions with exponential backoff (2s, 4s, 8s, 16s) on packet loss. Each retransmission doubles energy consumption.
The Fix: Use NON (Non-Confirmable) messages for periodic telemetry where the next reading supersedes the previous one. Reserve CON for:
- Actuator commands:
PUT /valve/state {"open": true}- must confirm execution - Alert notifications:
POST /alarm {"type": "intrusion"}- cannot be missed - Configuration changes:
PUT /config {"interval": 60}- must acknowledge receipt - Firmware blocks: Block2 transfers with CON ensure no gaps in firmware image
For a sensor sending temperature every 30 seconds, missing one reading is acceptable (next reading in 30s). Energy comparison:
| Message Type | Packets/Reading | Energy (mJ) | 5-Year Battery |
|---|---|---|---|
| NON | 1 | 1.5 | Achievable |
| CON (no loss) | 2 | 3.0 | 2.5 years |
| CON (10% loss) | 2.4 avg | 3.6 | 2.1 years |
Use application-level aggregation with NON: if 3 consecutive readings fail to reach the gateway (detected via heartbeat), trigger a single CON recovery message with recent readings.
1229.9 Visual Reference: CoAP Message Types
Understanding when to use each message type is essential for designing efficient IoT communication: - CON: When you must know the message was received (commands, alerts) - NON: When delivery confirmation isn’t worth the overhead (frequent telemetry) - Observe: When you need real-time updates without polling
1229.10 Summary
This chapter covered CoAP’s communication methods and patterns for constrained IoT environments:
- CoAP Methods: GET, POST, PUT, DELETE mirror HTTP but with 90-95% smaller headers (4-byte fixed header vs 200+ bytes)
- Confirmable vs Non-Confirmable: CON provides reliability with ACKs and retries; NON minimizes power for high-frequency telemetry where occasional loss is acceptable
- Polling vs Observe: Observe pattern can reduce bandwidth by 97%+ for slowly-changing data by pushing updates only on state changes
- Common Pitfalls: Using CON for all messages wastes battery; treating CoAP like HTTP ignores its efficiency optimizations
1229.11 Knowledge Check
1229.12 What’s Next
In the next chapter, CoAP Implementation Labs, you’ll write actual CoAP client and server code in Python and Arduino, putting these concepts into practice.
Key Takeaways: - Use CON for commands, NON for telemetry - not all messages need confirmation - Observe pattern provides 97%+ bandwidth savings for slowly-changing data - CoAP is NOT just HTTP over UDP - it has unique features optimized for constrained devices - Idempotency of PUT/GET/DELETE enables safe retries on unreliable networks