Computer science fundamentals for working engineers path · Between machines · Topic 9 of 13

The network stack: TCP, UDP and congestion control

Not started

Networking is built in layers. At the bottom, links such as Ethernet and Wi-Fi move frames between neighbouring machines. IP, the internet layer, gives every host an address and forwards packets hop by hop toward it, with no guarantee they arrive. On top of IP, a transport protocol decides what applications get: TCP provides a reliable, ordered byte stream, and UDP provides individual datagrams with no guarantees at all. Your HTTP request, database query or gRPC call rides on one of them.

Why it matters: Connection timeouts, slow first requests, head-of-line blocking and 'the network is slow but the bandwidth is fine' all come from how TCP and UDP behave.

  1. 1Layers

    Applications (HTTP, DNS) run on transports (TCP, UDP, QUIC), which run on IP, which runs on links like Ethernet and Wi-Fi. Each layer only talks to its neighbours.

  2. 2IP is best effort

    Packets can be lost, duplicated, reordered or delayed. IP routes each one independently and promises nothing.

  3. 3TCP adds reliability

    A three-way handshake, sequence numbers, acknowledgements and retransmission turn packets into an ordered, reliable byte stream.

  4. 4Congestion control shares the pipe

    TCP starts slowly and grows its sending window until loss or delay says the path is full, then backs off.

1

How it works

The explanation, with examples you can run.

UDP: just datagrams

UDP (RFC 768) adds little to IP: source and destination ports, a length and a checksum. Each datagram is sent on its own; it may be lost, duplicated or reordered, and the sender isn't told. There is no connection set-up, so the first packet can carry data. That suits DNS lookups (one question, one answer, retry if nothing comes back), real-time media and games (where late data is useless), and protocols that want to build their own reliability, like QUIC.

TCP: a reliable stream

TCP (RFC 9293) turns unreliable packets into an ordered, reliable stream of bytes between two endpoints:

  • Handshake. The client sends SYN with its initial sequence number, the server answers SYN-ACK with its own, and the client sends ACK. That costs one round trip before data flows.
  • Sequence numbers and acknowledgements. Every byte is numbered. The receiver acknowledges what it has received in order, and the sender retransmits anything not acknowledged in time or reported missing.
  • Flow control. The receiver advertises a window: how much it can buffer. A slow reader makes the sender wait instead of being flooded.
  • Teardown. Each side sends FIN when done. The side that closes first keeps the connection in TIME_WAIT for a while, so delayed packets can't confuse a new connection on the same ports.

Reliability has a cost: if one packet is lost, everything after it waits in the receiver's buffer until the retransmission arrives, even if it belongs to an unrelated request on the same connection. This is head-of-line blocking, and it is the main reason HTTP/3 runs over QUIC, which multiplexes independent streams over UDP so a loss on one stream doesn't stall the others.

Congestion control

Flow control protects the receiver; congestion control protects the network between. The sender keeps a congestion window, a limit on unacknowledged data in flight. RFC 5681 describes the classic algorithm:

  • Slow start: begin with a small window (about 10 packets on modern systems) and roughly double it every round trip.
  • Congestion avoidance: past a threshold, grow by about one packet per round trip.
  • Back off on loss: a lost packet is taken as a sign of congestion, so the window is cut, typically in half.

Linux uses CUBIC by default, and Google's BBR estimates bandwidth and round-trip time instead of waiting for loss. All of them mean a new connection starts slow. That is why connection reuse (HTTP keep-alive, connection pools), a CDN close to the user, and fewer round trips matter more than raw bandwidth for most web traffic.

Ports and sockets

An IP address identifies a host; a port (0 to 65535) identifies an application on it. A TCP connection is identified by four values: source IP, source port, destination IP, destination port. A server listens on one port and accepts many connections, each with a different client address and port. Programs reach all of this through sockets, the operating system's interface to the network, which the Linux path explores with ss and strace.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.How many network round trips does a new TCP connection need before the client can send its first byte of request data?
  2. 2.Why do video calls and online games often use UDP rather than TCP?
  3. 3.A file download over a new connection starts slowly and speeds up over the first second. What is the main reason?

0 of 3 right so far. Get all three to finish this topic.