Topic 2.3
Reliability, Flow Control, Congestion & Connection States
In one line
TCP guarantees ordered, reliable delivery with sequence numbers, acknowledgements, and retransmission, adapts its speed to the receiver and the network, and moves through states like ESTABLISHED, TIME_WAIT, and CLOSE_WAIT that tell you what's happening.
Key ideas
- 01
RELIABILITY: every byte has a SEQUENCE NUMBER; the receiver ACKNOWLEDGES what it got; missing data is RETRANSMITTED after a timeout or duplicate ACKs. The application sees a clean, ordered byte stream and never sees the loss, only the delay.
- 02
FLOW CONTROL: the receiver advertises a WINDOW (how many bytes it can accept). A slow consumer shrinks the window and the sender waits. This is why a slow client can hold server resources: backpressure travels all the way to the sender.
- 03
CONGESTION CONTROL: TCP starts slowly (SLOW START) and increases its sending rate until it sees loss or delay, then backs off. Algorithms like CUBIC (the Linux default) and BBR shape this. Consequence: new connections start slow, and throughput on high-latency links is limited by window ÷ RTT. That's another reason to reuse connections.
- 04
STATES to recognise in
ss: LISTEN, SYN-SENT (waiting for SYN-ACK; stuck here means blocked by a firewall), ESTABLISHED, CLOSE_WAIT (the peer closed, OUR application hasn't; lots of these usually means an application bug not closing sockets), TIME_WAIT (we closed first; kept for up to 2×MSL, 60 s on Linux, to absorb late packets). - 05
Huge numbers of TIME_WAIT on a client come from opening and closing many short connections, which is a pool or keep-alive problem, not a kernel one. Resist copying random sysctl 'fixes' from the internet; fix connection reuse first.
- 06
Nagle's algorithm and delayed ACKs can add ~40 ms to small request/response exchanges; latency-sensitive protocols set
TCP_NODELAY(most HTTP and database clients already do).
Code & diagrams
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn # count connections by state
ss -tn state close-wait # who isn't closing sockets?
ss -ti dst example.com # per-connection cwnd, rtt, retransmits
sysctl net.ipv4.tcp_congestion_control # cubic (default) or bbrExplain it without notes
A service has 12,000 connections in CLOSE_WAIT and is running out of file descriptors. Whose bug is it, and why?
Practice
With 150 ms RTT and a 64 KB effective window, what's the maximum throughput of a single TCP connection?
Trade-offs
- ↔
TCP's guarantees are exactly what most applications need, but they come with head-of-line blocking: one lost packet delays everything behind it in that connection. That's the motivation for QUIC (Topic 2.4).
Done when you can
I can explain sequence numbers, ACKs, and retransmission.
I know what flow control and congestion control each protect.
I can interpret LISTEN, SYN-SENT, ESTABLISHED, CLOSE_WAIT, and TIME_WAIT counts.