Skip to main content

The Transport Layer: TCP and UDP

Overview

The transport layer is where "get some bytes from A to B" becomes either a reliable, ordered stream (TCP) or a fast, minimal, unordered datagram service (UDP). Almost everything you do online rides on one of these two protocols, and the choice between them is a genuine engineering tradeoff, not just a historical accident — reliability and ordering guarantees cost latency and overhead that some applications can't afford.

Core Concepts

TermMeaning
PortA 16-bit number identifying a specific application/service on a host, alongside its IP address.
SegmentTCP's PDU: a header (ports, sequence/ack numbers, flags, window size) plus a chunk of stream data.
Sequence numberA per-byte counter TCP uses to detect loss, reordering, and duplication.
ACK (acknowledgment)A signal from the receiver confirming which sequence numbers it has successfully received.
Flow controlThe receiver telling the sender "don't send more than I can currently buffer" — protects the receiver.
Congestion controlThe sender (and network) inferring how much the network path can currently carry without overload — protects the network.

Architecture / Mechanism: The TCP Three-Way Handshake

Before exchanging any application data, TCP establishes a connection so both sides agree on starting sequence numbers:

Each side proposes an initial sequence number (ISN); the SYN-ACK both acknowledges the client's ISN and proposes the server's own. After the final ACK, both sides have confirmed they can send and receive, and the connection moves to the ESTABLISHED state.

That correctness has a price, and the price is measured in round trips:

Timeline between a client and server: a connection request arrow at 0 ms, an acknowledgement arriving back at 34 ms, and the first application data sent at 68 ms
One full round trip is spent before a single byte of application data moves. On a 34 ms path that is 68 ms of latency the user pays for nothing they asked for. Wikimedia Commons, Public domain

This is the single most important number in web performance work. A fresh HTTPS connection costs that round trip plus the TLS handshake's own, which is why connection reuse (keep-alive), TLS session resumption, and QUIC's 0-RTT and 1-RTT handshakes all exist — every one of them is an attempt to delete round trips from this picture.

Reliability Mechanisms

TCP guarantees ordered, complete delivery (or an error if that's impossible) using:

  • Sequence numbers on every byte, so the receiver can detect gaps and reorder out-of-order segments.
  • Acknowledgments, telling the sender which data has arrived.
  • Retransmission, triggered either by a timeout (no ACK received in time) or by duplicate ACKs signaling the receiver got data past a gap (fast retransmit).
  • Checksums, detecting corrupted segments so they're treated as if lost.

Flow Control vs. Congestion Control

These solve two genuinely different problems and are easy to conflate:

  • Flow control protects a slow receiver from being overwhelmed — it's purely between the two endpoints, communicated via the TCP header's window size field.
  • Congestion control protects the shared network from being overwhelmed by all the traffic crossing it — algorithms like slow start and congestion avoidance (originally Tahoe/Reno, now more commonly Cubic or BBR) let the sender infer available capacity from signals like loss and latency, since no router tells TCP directly how congested it is.

The actual send rate is limited by min(cwnd, rwnd) — whichever constraint is currently tighter.

UDP's Simplicity

UDP has no handshake, no sequence numbers, no retransmission, and no congestion control built in — just a header with source/destination port, length, and a checksum, wrapped around whatever payload the application provides. Delivery, ordering, and loss recovery (if needed at all) are the application's problem, not the transport's.

Practical Usage

Inspecting active connections and their state:

$ ss -tan | head -5
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.1.10:54321 93.184.216.34:443
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
TIME-WAIT 0 0 192.168.1.10:54444 93.184.216.34:80

ESTAB connections have completed the three-way handshake; TIME-WAIT is a connection that's been closed but is held briefly so any delayed duplicate segments from the old connection can't be mistaken for a new one.

Capturing a real handshake with tcpdump:

$ sudo tcpdump -i any -n 'tcp port 443 and host 93.184.216.34'
14:01:00.001 IP 192.168.1.10.54321 > 93.184.216.34.443: Flags [S], seq 100, win 64240
14:01:00.045 IP 93.184.216.34.443 > 192.168.1.10.54321: Flags [S.], seq 5000, ack 101, win 65160
14:01:00.046 IP 192.168.1.10.54321 > 93.184.216.34.443: Flags [.], ack 5001, win 64240

[S] = SYN, [S.] = SYN-ACK (SYN + ACK flags), [.] = ACK — exactly the three messages of the handshake, visible on the wire.

Edge Cases & Pitfalls

UDP gives you no delivery guarantee at all

If you build a protocol on UDP, loss, reordering, and duplication are all things your application must handle if it cares about them — there is no free retransmission. This is by design: DNS retransmits at the application level with simple timeouts, while QUIC (HTTP/3's transport) builds a full reliability and congestion-control layer on top of UDP precisely because it needs TCP-like guarantees without TCP's specific head-of-line-blocking behavior.

  • Head-of-line blocking: because TCP delivers strictly in order, one lost segment stalls delivery of all data behind it to the application, even if that later data already arrived — a major motivation for QUIC/HTTP/3 moving away from TCP.
  • A half-open connection (e.g., a client crashes mid-handshake) can leave a server holding resources — SYN flood attacks deliberately exploit this by never completing handshakes.
  • Congestion control behavior varies by OS/kernel (Cubic is Linux's long-time default; BBR is increasingly used) — the "same" TCP connection can behave differently depending on which algorithm either endpoint runs.

Comparisons

AspectTCPUDP
Connection setupThree-way handshake requiredNone — send immediately
OrderingGuaranteedNot guaranteed
ReliabilityRetransmits lost dataNone built in
Congestion/flow controlBuilt inNone built in
OverheadHigher (headers, ACKs, state)Minimal
Typical usesWeb (HTTP/1.1, HTTP/2), email, file transferDNS, video/voice calls, online gaming, QUIC/HTTP/3

References

  • IETF, RFC 9293Transmission Control Protocol (TCP), the current consolidated TCP specification (obsoletes the original RFC 793).
  • IETF, RFC 768User Datagram Protocol.
  • IETF, RFC 5681TCP Congestion Control.

Books & Videos

  • Kurose & Ross, Computer Networking: A Top-Down Approach — the transport-layer chapter is the standard modern treatment of TCP reliability and congestion control.
  • W. Richard Stevens, TCP/IP Illustrated, Volume 1 — the classic byte-level walkthrough of the TCP handshake, retransmission, and window mechanics.
  • Ilya Grigorik, High Performance Browser Networking (free online) — Part I, "Primer on Latency and Bandwidth" and the TCP/UDP chapters, from a web-performance angle.