Scenario: A logistics company operates a 50,000 m² warehouse with 2,000 pallet-tracking sensors. Each sensor reports location updates (12-byte GPS + 8-byte metadata) every 60 seconds. Sensors are battery-powered (2× AA, 3,000 mAh) and must last 2+ years. The warehouse has existing Wi-Fi coverage (50 access points). Current system uses HTTP/TCP, but battery life is only 6 months. Engineering investigates alternatives.
Step 1 — Current System Analysis (HTTP/TCP over Wi-Fi)
Message breakdown:
HTTP POST /api/location HTTP/1.1
Host: warehouse.local
Content-Type: application/json
Content-Length: 45
{"sensor_id": "PAL-1234", "lat": 37.7749, "lon": -122.4194, "battery": 3.2}
Headers: ~150 bytes (HTTP request line + headers)
JSON payload: 45 bytes (inefficient text encoding)
TCP header: 20 bytes
IPv6 header: 40 bytes
Wi-Fi header: 36 bytes
Total: 291 bytes per message
Battery calculation:
Messages per day: 1440 minutes ÷ 1 = 1440 messages
Daily data: 1440 × 291 = 419,040 bytes
TX time at 54 Mbps: 419,040 × 8 ÷ 54,000,000 = 62 ms
Power consumption:
- Wi-Fi TX: 200 mW
- Wi-Fi idle (connected): 10 mW
- TX energy: 200 mW × 0.062s = 12.4 mJ = 0.0034 mAh
- Idle energy (23h 59m): 10 mW × 86,337.9s = 863.4 J = 240 mAh
- Total: 240 mAh/day
Battery life: 3000 mAh ÷ 240 mAh/day = 12.5 days
Wait—calculations show 12.5 days but reality is 6 months? What’s missing?
The original analysis assumed continuous Wi-Fi connection. Real implementation uses Wi-Fi sleep mode: - Sleep mode: 1 mA (not 0.01 mW — power-saving mode still polls beacon) - Wake, connect, transmit, disconnect cycle adds overhead
Corrected calculation:
Wi-Fi wake cycle per message:
1. Wake from sleep: 200 mW × 0.5s = 100 mJ
2. Association: 150 mW × 1.0s = 150 mJ
3. DHCP (if needed): 150 mW × 0.5s = 75 mJ
4. HTTP POST: 200 mW × 0.1s = 20 mJ
5. Disconnect: 100 mW × 0.2s = 20 mJ
Total per message: 365 mJ = 0.101 mAh
Daily Wi-Fi energy: 1440 × 0.101 = 145.4 mAh
Daily sleep energy: 1.0 mA × 24h = 24 mAh
Total: 169.4 mAh/day
Battery life: 3000 ÷ 169.4 = 17.7 days
Still wrong! What else?
Real-world factors:
- Retry logic: 10% Wi-Fi packet loss requires retries (1.1× multiplier)
- Keep-alive: Some connections maintain TCP for 5 minutes (saves reconnection)
- Temperature: Warehouse -5°C to 35°C reduces battery capacity by 20%
Final realistic calculation:
With keep-alive (5-min windows):
- 5-min window has 5 messages
- Connect once: 325 mJ
- 5× HTTP POST: 5 × 20 = 100 mJ
- Total: 425 mJ for 5 messages = 85 mJ/message = 0.024 mAh/message
Daily energy: 1440 × 0.024 = 34.6 mAh (TX) + 24 mAh (sleep) = 58.6 mAh/day
Effective capacity: 3000 × 0.80 = 2400 mAh
Battery life: 2400 ÷ 58.6 = 41 days ≈ 1.4 months
Closer to observed 6 months with aggressive connection reuse...
Step 2 — Proposed Solution: CoAP/UDP with Keep-Alive Alternative
Instead of TCP keep-alive, use CoAP Observe pattern:
New message format:
CoAP CON message (binary):
- CoAP header: 4 bytes
- Token: 2 bytes
- URI-Path: 8 bytes (/loc)
- Binary payload: 12 bytes (3 floats: lat, lon, battery)
Total application: 26 bytes
UDP header: 8 bytes
IPv6 header: 40 bytes
Wi-Fi header: 36 bytes
Total: 110 bytes (62% reduction from 291 bytes!)
Power advantage:
CoAP uses UDP = no TCP connection state
Sensors send UDP packet and immediately sleep
No keep-alive windows needed
Per-message energy:
1. Wake: 200 mW × 0.5s = 100 mJ
2. DNS lookup (cached): 0 mJ
3. CoAP CON: 200 mW × 0.05s = 10 mJ (faster, smaller packet)
4. Sleep: immediate
Total: 110 mJ = 0.031 mAh/message
Daily energy: 1440 × 0.031 = 44.6 mAh (TX) + 24 mAh (sleep) = 68.6 mAh/day
Battery life: 2400 ÷ 68.6 = 35 days ≈ 1.2 months
Still not 2 years! Need a different approach...
Step 3 — Alternative: Zigbee Mesh + Gateway Bridge
Replace Wi-Fi with 802.15.4/Zigbee mesh:
Hardware change: Zigbee module instead of Wi-Fi
Message format:
- 802.15.4 header: 8 bytes (compressed)
- 6LoWPAN header: 6 bytes
- UDP (compressed): 4 bytes
- CoAP: 4 bytes
- Payload: 12 bytes (binary)
Total: 34 bytes
Zigbee power profile:
- TX: 20 mA at 3V = 60 mW
- Sleep: 3 µA at 3V = 0.009 mW
Per-message energy:
TX time: 34 bytes × 8 bits ÷ 250,000 bps = 1.088 ms
TX energy: 60 mW × 0.001088s = 0.065 mJ = 0.000018 mAh
Daily energy:
TX: 1440 × 0.000018 = 0.026 mAh
Sleep: 0.003 mA × 24h = 0.072 mAh
Total: 0.098 mAh/day
Battery life: 2400 ÷ 0.098 = 24,490 days = 67 years!
(Limited by battery self-discharge to ~10 years)
Step 4 — Cost-Benefit Analysis
| Battery life |
6 months |
1.2 months |
10 years |
| Hardware cost/sensor |
$8 (Wi-Fi) |
$8 (Wi-Fi) |
$12 (Zigbee) |
| Infrastructure |
50 APs (existing) |
50 APs (existing) |
20 gateways ($300 ea) |
| Development effort |
Done |
2 weeks |
6 weeks |
| Battery replacements (5yr) |
10× @ $2 = $20/sensor |
50× @ $2 = $100/sensor |
0× |
| Total 5-year cost (2000 sensors) |
$56K |
$216K |
$30K |
Winner: Zigbee mesh despite higher upfront cost and development effort.
Why CoAP/Wi-Fi failed: Wi-Fi’s idle listening power (1-10 mA) dominates energy consumption even with CoAP’s efficiency gains. The protocol optimization (HTTP→CoAP) only improved TX energy, which was already <1% of total consumption.
Key insight: For battery-powered IoT, radio technology choice (Wi-Fi vs Zigbee) matters 100× more than application protocol choice (HTTP vs CoAP) when sleep current differs by 3 orders of magnitude (1 mA vs 3 µA). Protocol optimization is meaningless if you chose the wrong wireless technology.
Implementation: Zigbee sensors → Border routers (every 100m) → Ethernet gateway → CoAP-to-HTTP proxy → Warehouse management system. The gateway handles protocol translation, preserving existing cloud integration.