Networking & Communication

TCP vs UDP

18 min Lesson 4 of 10

TCP vs UDP

Every byte you send over the internet travels inside a transport-layer packet. Two protocols dominate this layer: TCP (Transmission Control Protocol) and UDP (User Datagram Protocol). Choosing the wrong one can tank the reliability of a banking service or double the latency of a live video game. Understanding the difference — not just the textbook definition, but the real engineering trade-offs — is essential for system design.

What Is TCP?

TCP is a connection-oriented, reliable, ordered, and error-checked protocol. Before a single byte of application data moves, TCP performs a three-way handshake:

  1. Client sends SYN — "I want to connect."
  2. Server replies SYN-ACK — "Agreed, ready."
  3. Client sends ACK — "Connection established."

After that, every segment sent by one side is acknowledged (ACK) by the other. If an acknowledgment does not arrive within a timeout window, the sender retransmits. TCP also enforces in-order delivery: if segment 4 arrives before segment 3, TCP buffers it and only delivers both to the application once segment 3 arrives too. Finally, TCP's congestion control algorithms (Slow Start, AIMD) automatically throttle the send rate when the network is congested.

TCP Three-Way Handshake and Data Transfer Client Server SYN SYN-ACK ACK (Connection established) DATA (segment 1, 2, 3…) ACK (received ok) 3-Way Handshake Reliable Data Transfer
TCP three-way handshake followed by acknowledged data transfer — every segment gets an ACK before the connection proceeds.
TCP head-of-line blocking: Because TCP enforces in-order delivery at the OS level, a single lost packet stalls all subsequent segments in that stream — even if they have already arrived. This is a critical bottleneck to understand when designing latency-sensitive systems.

What Is UDP?

UDP is connectionless and unreliable. There is no handshake, no acknowledgment, no retransmission, and no ordering guarantee. A UDP sender fires a datagram into the network and immediately moves on. If the packet is dropped, corrupted, or arrives out of order, the protocol does nothing — it is entirely the application's responsibility to handle those cases (or ignore them).

This sounds like a liability, but it is also UDP's superpower. The absence of handshake and retransmission overhead makes UDP:

  • Faster — no round-trip required before data flows.
  • Lower latency — no queuing behind retransmitted segments.
  • Lighter on the network stack — the UDP header is just 8 bytes vs. TCP's 20-60 bytes.

Side-by-Side Comparison

TCP vs UDP Side-by-Side Comparison TCP UDP Connection: 3-way handshake required Reliability: Guaranteed delivery Ordering: Strict in-order delivery Error handling: Checksum + retransmit Congestion control: Built-in (Slow Start) Header size: 20-60 bytes Speed: Slower (overhead) Use cases: HTTP, email, file transfer Connection: None (fire and forget) Reliability: Best-effort, no guarantee Ordering: None — app must handle it Error handling: Checksum only Congestion control: None built-in Header size: 8 bytes Speed: Fast (minimal overhead) Use cases: Video, gaming, DNS, VoIP
TCP guarantees delivery and order at the cost of latency; UDP trades guarantees for raw speed.

When to Use TCP

Use TCP whenever losing or reordering data would produce a corrupt or incorrect result:

  • HTTP/HTTPS — a missing byte in an HTML page or JSON API response renders it broken.
  • Databases over a network — a dropped byte in a SQL query or result set corrupts the operation.
  • File transfers (FTP, S3 uploads) — a missing segment silently corrupts the file.
  • Email (SMTP, IMAP) — emails must arrive intact.
  • SSH / remote admin — a dropped character in a shell command has consequences.

Roughly speaking: if you would need to implement retransmission and ordering yourself in UDP, just use TCP instead.

When to Use UDP

Use UDP when timeliness beats completeness — a stale retransmitted packet is worse than no packet:

  • Live video & audio streaming — a 200 ms-old video frame is useless; skip it and render the next one. WebRTC (used by Zoom, Google Meet) runs over UDP-based DTLS/SRTP.
  • Online multiplayer games — player positions are sent dozens of times per second. A retransmit of a 50 ms-old position would arrive after the current position update anyway.
  • DNS — a single-packet request/response that fits in one datagram; a TCP handshake would double the lookup time.
  • DHCP — network bootstrapping before an IP address is even assigned.
  • IoT sensor telemetry — a missed temperature reading is acceptable; low overhead on constrained devices matters.
  • QUIC (HTTP/3) — Google's QUIC protocol runs over UDP so it can implement its own smarter, multiplexed reliability layer without the OS-level head-of-line blocking of TCP.
QUIC is the modern answer: QUIC takes the best of both worlds — it runs over UDP but implements its own reliable, encrypted, multiplexed streams. HTTP/3 is built on QUIC. If you are designing a new protocol for modern infrastructure, QUIC is worth serious consideration over raw TCP.

The Real Numbers: Latency Cost of TCP Handshake

Every new TCP connection pays a minimum of 1 RTT (round-trip time) before data can flow, plus another RTT for TLS if HTTPS is used (TLS 1.3 reduced this to 1 RTT). On a cross-continental link where RTT is ~100 ms, this means:

  • TCP handshake alone: 100 ms
  • TCP + TLS 1.3: 200 ms
  • TCP + TLS 1.2 (older): 300 ms
  • UDP (no handshake): 0 ms setup, first packet goes immediately

This is why connection pooling (reusing TCP connections) is so important in HTTP/1.1, and why HTTP/2 multiplexing and HTTP/3 (QUIC) eliminate the per-request connection cost entirely.

Hybrid Approach: UDP with Application-Level Reliability

Sophisticated systems sometimes choose UDP and then implement only the reliability they actually need. For example, a multiplayer game might:

  • Send player positions over UDP — unreliable, unordered, accept drops.
  • Send critical game events (player died, item picked up) over the same UDP socket but with a custom sequence number + selective ACK scheme — just enough reliability for game-state consistency.

This granular control is impossible with TCP, where you take all-or-nothing reliability for the entire stream.

Do not roll your own reliability protocol on UDP unless you genuinely need that control. Custom reliable-UDP implementations are notoriously hard to get right (congestion fairness, retransmit storms, reorder buffers). For most services, HTTP/2 over TCP or QUIC are better defaults.

Key Design Heuristics

  • Default to TCP (via HTTP/2 or HTTP/3) for any service where data integrity matters.
  • Choose UDP for real-time media, gaming, or DNS — where latency matters more than completeness.
  • Consider QUIC/HTTP/3 when you need reliability but also care about head-of-line blocking and connection setup latency.
  • Never let "UDP is faster" be the only reason to switch — measure the actual RTT and packet-loss rates in your environment first.