15  Transport Plain English Guide

In 60 Seconds

TCP is like certified mail – you get confirmation of delivery but it is slow and expensive. UDP is like throwing paper airplanes – fast and cheap but no guarantee they arrive. For IoT, this analogy translates directly: a 2MB firmware update needs TCP’s reliability (every byte matters), while a temperature sensor sending readings every 5 seconds should use UDP (the next reading replaces a lost one). UDP’s 8-byte header vs TCP’s 20+ bytes saves significant battery life across millions of transmissions.

Key Concepts
  • Postal Service Analogy for TCP: TCP is like registered mail with tracking: each letter (segment) gets a tracking number (sequence number), delivery confirmation (ACK), and can be resent if lost (retransmission); the postal service ensures ordered delivery
  • Shouting in a Crowd Analogy for UDP: UDP is like shouting a message in a crowd — no guarantee the right person hears it, no confirmation, but you can reach everyone quickly without individual conversations
  • Phone Call vs Text Message: TCP = phone call (established connection, conversation, disconnect); UDP = text message (fire-and-forget, no connection)
  • Orchestra Conductor Analogy for Flow Control: TCP flow control = orchestra conductor controlling tempo; if musicians fall behind, conductor slows down (sender reduces rate when receiver buffer fills)
  • Congestion Window as a Pipe: TCP congestion control adjusts the “pipe diameter” (congestion window) based on observed packet loss; starts narrow (slow start), widens quickly, narrows on loss signal
  • UDP in IoT Sensor Networks: Temperature sensor → UDP → hub → cloud; if one reading is lost, the next one arrives 30 seconds later; loss is acceptable because data is continuous
  • ACK Number as a Bookmark: TCP ACK number tells the sender “I have received everything up to byte N, continue from N+1” — like a bookmark showing where you left off in a book
  • TCP Handshake as a Formal Introduction: SYN = “Hello, I want to communicate”; SYN-ACK = “Hello back, I’m ready”; ACK = “Great, let’s start” — a polite 3-step introduction before the conversation begins

15.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Explain TCP and UDP using everyday analogies that non-technical stakeholders can understand
  • Calculate overhead differences between TCP and UDP for IoT sensor scenarios
  • Analyze battery impact of transport protocol choices on constrained devices
  • Select TCP or UDP for a given IoT use case based on data characteristics and reliability requirements
  • Justify protocol choices for real-world deployment scenarios using quantitative overhead and energy arguments
  • Distinguish time-sensitive telemetry from mission-critical data to apply the correct reliability guarantee

This chapter explains transport protocols using everyday language and familiar comparisons. No jargon, no equations – just clear explanations of how data gets reliably delivered between devices. If other chapters felt too technical, start here to build your intuition before diving into the details.

“Let me explain TCP and UDP the simplest way possible,” said Sammy the Sensor. “TCP is registered mail – you get a tracking number, delivery confirmation, and they retry if it fails. UDP is a postcard – you write it, drop it in the mailbox, and hope it arrives.”

“The overhead difference is staggering,” explained Max the Microcontroller. “TCP’s header is at least 20 bytes. For a 10-byte sensor reading, that is 200 percent overhead – more envelope than letter! UDP’s header is just 8 bytes, so the overhead is only 80 percent.”

“For a sensor sending readings every 5 seconds, the math is clear,” added Bella the Battery. “Over a day, that is 17,280 readings. With TCP, those extra 12 bytes per packet add up to 200 kilobytes of wasted overhead. On a constrained network, that is a significant chunk of bandwidth and battery.”

“The bottom line is simple,” concluded Lila the LED. “If the next reading replaces a lost one, use UDP. If losing the data would be catastrophic – like a firmware update or a fire alarm – use TCP. Match the delivery guarantee to how important the data actually is.”

15.2 In Plain English: Transport Protocols Explained

Think of transport protocols as different ways to send packages, but for data instead of physical items.

15.2.1 TCP: The Registered Mail Service

TCP is like sending a package via FedEx with signature confirmation:

  • Before sending: You call the recipient - they answer - you confirm they’re ready (3-way handshake)
  • During delivery: FedEx tracks every step, sends you updates, requires signature
  • If something goes wrong: They try again, and again, until it arrives or you cancel
  • After delivery: You get confirmation it was received and signed for
  • Cost: Expensive (lots of steps, tracking, confirmation)
  • Time: Takes longer (all the verification slows it down)
  • Guarantee: You KNOW it arrived, in the right order, intact

Real-world TCP example: You’re updating your smart doorbell’s firmware. The file is 2 MB and contains critical code. If even one bit is wrong, your doorbell becomes a brick. TCP ensures every single byte arrives correctly, in order, with verification at every step.

15.2.2 UDP: The Paper Airplane Method

UDP is like throwing paper airplanes over a fence:

  • No setup: Just throw it and hope it lands
  • No tracking: You have no idea if it made it over the fence
  • No order: If you throw 3 airplanes, they might land 2nd, 1st, 3rd
  • No retries: If the wind blows one away, it’s gone forever
  • Cost: Free (just the effort to throw)
  • Time: Instant (no waiting for confirmation)
  • Guarantee: None - but maybe you don’t care

Real-world UDP example: Your temperature sensor sends “72 degrees F” every 10 seconds. If one message gets lost, who cares? Another one is coming in 10 seconds anyway. No point wasting energy confirming the old temperature when fresh data is about to arrive.

15.2.3 The Perfect Analogy: Text Message vs Phone Call

TCP (Phone Call) UDP (Text Message)
Must establish connection first Just send it
Know they picked up Don’t know if they read it
Conversation flows both ways One-way communication
Immediate feedback if disconnected No feedback at all
“Can you hear me now?” “Hope you got this!”
Takes more effort to setup Fire and forget

15.2.4 Why IoT Uses UDP So Much

Imagine you’re a battery-powered sensor in a field, miles from anywhere:

Scenario: Send temperature reading every hour

With TCP:

  1. Wake up from sleep (uses battery)
  2. Call the server: “Hey, are you there?” (uses battery)
  3. Wait for response: “Yes, I’m here!” (uses battery while waiting)
  4. Confirm: “OK, I’m sending data” (uses battery)
  5. Send: “Temperature is 72 degrees F” (uses battery)
  6. Wait for: “Got it, thanks!” (uses battery while waiting)
  7. Say goodbye: “OK, hanging up” (uses battery)
  8. Wait for: “Goodbye!” (uses battery while waiting)
  9. Go back to sleep

With UDP:

  1. Wake up from sleep (uses battery)
  2. Shout: “TEMPERATURE IS 72 degrees F!” (uses battery)
  3. Go back to sleep immediately

Result: UDP uses 1/8th the battery life for the same data!

For a battery-powered sensor (2000 mAh battery, 160 mA TX current, 0.01 mA sleep) sending 10-byte readings every 60 seconds:

UDP transmission: \[ \text{Packet} = 10 + 8 \text{ (UDP)} + 20 \text{ (IP)} = 38 \text{ bytes} \] \[ \text{TX time} = \frac{38 \times 8}{250{,}000} = 1.22 \text{ ms at 250 kbps} \] \[ \text{Energy} = 160 \text{ mA} \times \frac{1.22}{3{,}600{,}000} = 0.000054 \text{ mAh per reading} \]

Daily energy (1,440 readings): \(1{,}440 \times 0.000054 = 0.078 \text{ mAh TX} + 0.24 \text{ mAh sleep} = 0.318 \text{ mAh/day}\)

Battery life: \(2000 / 0.318 = 6{,}289 \text{ days} = \mathbf{17.2 \text{ years}}\)

TCP transmission (new connection each time): \[ \text{Handshake} = 3 \times 60 = 180 \text{ bytes} \] \[ \text{Data} = 10 + 20 \text{ (TCP)} + 20 \text{ (IP)} = 50 \text{ bytes} \] \[ \text{Teardown} = 2 \times 40 = 80 \text{ bytes} \] \[ \text{Total} = 310 \text{ bytes per reading} \] \[ \text{TX time} = \frac{310 \times 8}{250{,}000} = 9.92 \text{ ms} \] \[ \text{Energy} = 160 \times \frac{9.92}{3{,}600{,}000} = 0.000441 \text{ mAh per reading} \]

Daily energy: \(1{,}440 \times 0.000441 + 0.24 = 0.875 \text{ mAh/day}\)

Battery life: \(2000 / 0.875 = 2{,}286 \text{ days} = \mathbf{6.3 \text{ years}}\)

UDP extends battery life by 2.75× in this realistic scenario (sleep current dominates both cases, but TCP’s 8× transmission overhead still reduces life from 17.2 to 6.3 years).

15.2.5 When You MUST Use TCP (No Exceptions)

  • Firmware updates: If even 1 byte is wrong, device is bricked
  • Security keys: Encryption keys must be perfect or security fails
  • Financial data: Can’t lose payment information
  • Configuration commands: “Unlock door” message cannot be lost
  • Medical alarms: Critical health alerts require guaranteed delivery

15.2.6 When UDP Is The Smart Choice

  • Streaming video: Lost frame? Next one’s coming in 1/30th of a second
  • Temperature readings: Fresh data replaces old automatically
  • GPS location updates: Position changes constantly anyway
  • Voice calls: Brief audio dropout better than delayed audio
  • Gaming: Old player position irrelevant when new one arrives

The Golden Rule: If the next message makes the previous one irrelevant, use UDP. If every message matters forever, use TCP.

Quick Check: The Golden Rule in Practice

15.3 Real-World Example: The 100-Byte Sensor Reading

Let’s analyze a real IoT scenario with actual numbers to understand the overhead difference between TCP and UDP.

15.3.1 Scenario Setup

Device: Battery-powered soil moisture sensor Location: Agricultural field, Wi-Fi connection Data: Sends 100-byte sensor reading Frequency: Every 5 minutes (288 readings/day) Battery: 2000 mAh battery Radio: 50 mA TX current, 100 ms active per packet

15.3.2 UDP Transmission Breakdown

Transmission Summary:

  • Packets sent: 1
  • Total bytes: 128 bytes (100 payload + 8 UDP + 20 IP)
  • Transmission time: 100 ms
  • Energy per message: 50 mA × 0.1 s ÷ 3600 = 0.00139 mAh

15.3.3 TCP Transmission Breakdown

Transmission Summary:

  • Packets sent: 8 (SYN, SYN-ACK, ACK, DATA, ACK, FIN, ACK, FIN-ACK)
  • Total bytes: 460 bytes (100 payload + 360 bytes of transport/network headers across all packets; model counts each packet’s IP+TCP overhead including the data packet)
  • Transmission time: 800 ms (8 × 100 ms)
  • Energy per message: 50 mA × 0.8 s ÷ 3600 = 0.0111 mAh

15.3.4 Side-by-Side Comparison

Metric UDP TCP Difference
Packets 1 8 8x more
Total bytes 128 460 3.6x more
Overhead bytes 28 (22%) 360 (78%) 12.9x more
Data bytes 100 (78%) 100 (22%) Same payload
Transmission time 100 ms 800 ms 8x longer
Energy per message 0.00139 mAh 0.0111 mAh 8x more

15.3.5 Annual Battery Impact

Readings per year: 365 days × 24 hours × 12 per hour = 105,120 readings

Protocol Daily energy Battery Life
UDP 288 × 0.00139 = 0.40 mAh/day 2000 ÷ 0.40 = 5,000 days (~13.7 years)
TCP 288 × 0.0111 = 3.20 mAh/day 2000 ÷ 3.20 = 625 days (~1.7 years)

Result: TCP drains the battery 8x faster than UDP for the same data!

15.3.6 Cost Analysis (1000 Sensors)

Assumptions:

  • Battery replacement cost: $5 per sensor (technician visit to field)
  • UDP battery life: 5,000 days (0.07 replacements/year)
  • TCP battery life: 625 days (0.58 replacements/year)
Protocol Replacements/Year/Device Fleet of 1000 Annual Cost
UDP 0.073 73 $365
TCP 0.584 584 $2,920
Difference 511 extra $2,555 extra

For deployments where battery replacement requires a field technician visit, this cost compounds quickly. At $100/visit (agricultural field): UDP saves $51,100/year over TCP for 1,000 sensors.

15.3.7 When TCP Overhead Is Worth It

Firmware update scenario: 500 KB file, 1460-byte TCP segments (MSS)

Protocol Reliability Overhead Notes
UDP Near zero (2% loss per packet, 350+ packets) None Any lost packet = restart entire file
TCP ~99.9% ~2.7% of payload Automatic per-packet retry; trivial for large files

At 2% packet loss rate, the probability that all ~350 segments of a 500 KB file arrive intact via UDP is less than 0.1%. TCP’s per-packet ACK and automatic retransmission makes firmware updates reliable regardless of link quality.

Verdict: For a 500 KB firmware update, TCP’s ~2.7% header overhead is a small price for guaranteed delivery. For periodic 100-byte readings, TCP wastes 78% of every transmission on headers.

15.3.8 The Bottom Line

  • For 100-byte periodic readings: UDP uses 8x less energy, extends battery life 8x
  • For 500 KB firmware updates: TCP header overhead is ~2.7%; reliability is essential
  • Hybrid approach: UDP for telemetry + TCP for firmware = best of both worlds

15.4 Interactive: UDP vs TCP Overhead Calculator

Adjust the sliders to see how payload size, message rate, and battery parameters affect the overhead and battery life comparison between UDP and TCP.

Try It: Transport Overhead and Battery Life

15.5 Working Code: TCP vs UDP Overhead Calculator

The Python tool below shows the same calculation in runnable form, useful for adapting to your specific deployment parameters.

"""TCP vs UDP Overhead Calculator for IoT Deployments."""

def transport_comparison(payload_bytes, msgs_per_hour, battery_mAh=2000,
                         tx_mA=50, ms_per_packet=100, battery_cost=5.0,
                         num_devices=1000):
    """Compare TCP and UDP overhead for an IoT sensor deployment.

    Returns detailed cost analysis including battery and labor costs.
    """
    # Protocol overhead breakdown (bytes)
    udp = {
        "name": "UDP",
        "transport_header": 8,
        "ip_header": 20,      # IPv4; IPv6 would be 40
        "link_header": 14,    # Ethernet; 802.15.4 would be 25
        "packets_per_msg": 1, # Fire and forget
        "extra_packets": 0,   # No handshake, no ACK
    }
    tcp = {
        "name": "TCP",
        "transport_header": 20,  # Minimum; options add 12-40 more
        "ip_header": 20,
        "link_header": 14,
        "packets_per_msg": 1,
        "extra_packets": 7,   # SYN, SYN-ACK, ACK (x2 for setup+teardown) + ACK
    }

    results = {}
    for proto in [udp, tcp]:
        overhead = proto["transport_header"] + proto["ip_header"] + proto["link_header"]
        data_packet_bytes = payload_bytes + overhead

        # Extra packets (handshake etc.) carry only headers
        total_packets = proto["packets_per_msg"] + proto["extra_packets"]
        total_bytes = data_packet_bytes + proto["extra_packets"] * overhead

        overhead_pct = (total_bytes - payload_bytes) / total_bytes * 100
        efficiency = payload_bytes / total_bytes * 100

        # Battery calculations
        tx_time_ms = total_packets * ms_per_packet
        energy_per_msg_mAh = tx_mA * (tx_time_ms / 3_600_000)
        msgs_per_day = msgs_per_hour * 24
        daily_mAh = energy_per_msg_mAh * msgs_per_day
        battery_days = (battery_mAh * 0.8) / daily_mAh  # 80% usable

        # Annual cost per device fleet
        replacements_year = 365 / battery_days
        annual_labor = replacements_year * num_devices * battery_cost

        results[proto["name"]] = {
            "overhead_bytes": total_bytes - payload_bytes,
            "total_bytes": total_bytes,
            "packets": total_packets,
            "overhead_pct": overhead_pct,
            "efficiency_pct": efficiency,
            "battery_days": battery_days,
            "annual_cost": annual_labor,
        }

    # Print comparison
    print(f"\nTransport Protocol Comparison")
    print(f"Payload: {payload_bytes} bytes | Rate: {msgs_per_hour} msgs/hr")
    print(f"Fleet: {num_devices:,} devices | Battery: {battery_mAh} mAh")
    print("=" * 55)
    print(f"  {'Metric':<25s} {'UDP':>12s} {'TCP':>12s}")
    print(f"  {'-'*49}")

    for label, key, fmt in [
        ("Packets per message",  "packets",       "d"),
        ("Total bytes",          "total_bytes",    ",d"),
        ("Overhead bytes",       "overhead_bytes", ",d"),
        ("Protocol efficiency",  "efficiency_pct", ".1f"),
        ("Battery life (days)",  "battery_days",   ",.0f"),
        ("Annual fleet cost ($)","annual_cost",    ",.0f"),
    ]:
        u = results["UDP"][key]
        t = results["TCP"][key]
        suffix = "%" if "pct" in key else ""
        print(f"  {label:<25s} {u:>11{fmt}}{suffix} {t:>11{fmt}}{suffix}")

    saving = results["TCP"]["annual_cost"] - results["UDP"]["annual_cost"]
    ratio = results["TCP"]["battery_days"] / results["UDP"]["battery_days"]
    print(f"\n  UDP battery lasts {1/ratio:.1f}x longer than TCP")
    print(f"  Annual savings with UDP: ${saving:,.0f}")
    return results


# Scenario 1: Soil moisture sensor (from chapter example)
transport_comparison(payload_bytes=100, msgs_per_hour=12,
                     battery_mAh=2000, num_devices=1000)

# Scenario 2: Industrial temperature (frequent, small payloads)
transport_comparison(payload_bytes=20, msgs_per_hour=60,
                     battery_mAh=3000, num_devices=500)

# Scenario 3: Smart meter (large, infrequent)
transport_comparison(payload_bytes=500, msgs_per_hour=1,
                     battery_mAh=5000, num_devices=10000)

Copy this code to run locally with your own values. The results often surprise engineers who assume TCP’s overhead is “small.” For tiny IoT payloads (10-100 bytes), TCP’s handshake packets dominate the total transmission cost.

Common Pitfalls

Analogies help build intuition but can mislead when taken too literally. The “phone call” TCP analogy suggests TCP is always conversational and interactive — but TCP is also used for large bulk file transfers where the connection persists for minutes with no interaction. The “text message” UDP analogy suggests UDP is simple — but implementing reliable UDP (CoAP Confirmable) adds significant complexity not captured by the analogy. Always verify protocol behavior with the actual specification before relying on analogy-based reasoning.

TCP provides byte-stream reliability from socket to socket. It does NOT guarantee that the application processes the data successfully. A TCP ACK means “bytes received into the OS kernel buffer” — not “application read the data and processed it successfully.” Application-level acknowledgment (MQTT PUBACK, CoAP ACK with response code) is required to confirm end-to-end processing. Analogies that compare TCP to “guaranteed delivery” mislead developers into skipping application-layer acknowledgment for critical data.

“UDP loses packets” is true in theory but misleading in practice for local network applications. A UDP packet on a well-designed wired LAN has <0.001% loss probability. UDP packet loss is primarily caused by: application-layer congestion (receiver drops packets if processing is slow), router buffer overflows (network congestion), and weak signal (wireless interfaces). For IoT devices on a private LAN with light traffic, UDP loss may be negligible — measurement before assumption is essential.

This oversimplification misses the key IoT use case for UDP: CoAP (IETF standard), MQTT-SN, LwM2M, and other IoT protocols specifically chose UDP for constrained environments. UDP enables: stateless request-response, multicast, and smaller code footprint on MCUs with limited flash. When evaluating transport protocols for IoT, analyze the specific requirements rather than applying “UDP for games, TCP for serious applications” heuristics.

15.6 What’s Next

Continue building your understanding of transport protocols in IoT systems:

Chapter Focus Why Read It Next
Real-World Scenarios and Common Mistakes Disaster scenarios and pitfalls See how wrong protocol choices cause real failures; avoid the 7 most common mistakes
Hands-On Transport Lab ESP32 simulation with Wokwi Implement TCP and UDP side-by-side in runnable code and measure the overhead difference yourself
Transport Selection and Scenarios Decision frameworks Apply structured decision trees to classify any IoT use case and select the right protocol
Transport Protocol Fundamentals TCP/UDP internals Deepen understanding of headers, flow control, congestion control, and state machines
CoAP and Application Protocols CoAP over UDP Explore how CoAP adds optional reliability on top of UDP without TCP’s full overhead