Q01 — Why does TCP exist — what problem does it solve that the raw internet doesn't?
Why does the internet lose packets in the first place?
The internet is not a wire. It is a collection of independent routers, each making a local forwarding decision — "given this packet's destination, I'll send it out this interface." No router knows the full path. No router tracks whether a packet arrives.
The protocol that governs this is IP (Internet Protocol). IP is intentionally minimal: it wraps your data in a packet with a source address and destination address, and it best-effort delivers it. "Best-effort" is not a marketing hedge — it is a design choice. IP makes no promises. A packet can be:
- Lost — a router's buffer fills up under load, and it silently drops packets
- Reordered — two packets take different routes; the second one arrives first
- Duplicated — a router retransmits a packet it thinks was dropped, but it wasn't
- Corrupted — a flipped bit somewhere in transit
IP will not tell you any of this happened. Your data just... doesn't arrive.
Why does this matter — can't the application just deal with it?
For some applications, yes. Send a DNS query, get a response back, done. If the response is lost, you just retry. No real harm.
But consider sending a file. The file is split into thousands of packets sent across the network. If packet 472 is lost, you don't want to receive packets 473 through 4000 and then discover the file is corrupt. You want the receiver to say "I'm missing 472, please resend it." You want the sender to know when the receiver has gotten everything. You want the packets reassembled in the right order even if they arrived scrambled.
Building all of this correctly inside every application that needs reliable data transfer is a terrible idea. It's complex, subtle, and would be reimplemented slightly differently by every team. This is the problem TCP solves — it provides a reliable, ordered, byte-stream abstraction on top of the unreliable IP layer, so applications don't have to think about packet loss, reordering, or duplication.
How does TCP actually guarantee delivery?
TCP uses sequence numbers. Every byte of data sent over a TCP connection has a position — byte 0, byte 1, byte 2, and so on. Each packet carries the sequence number of the first byte it contains.
The receiver uses these numbers to do two things: reassemble packets in the correct order regardless of arrival order, and detect gaps (a missing packet means there's a hole in the sequence).
When the receiver gets data, it sends back an acknowledgment (ACK) — "I've received everything up to byte N." If the sender doesn't receive an ACK within a timeout window, it retransmits the unacknowledged data. This is how TCP handles packet loss: the sender keeps retrying until the receiver confirms receipt.
Duplication is also handled by sequence numbers — if a duplicate packet arrives, the receiver sees that it already has those bytes and discards the duplicate silently.
Why does TCP do a 3-way handshake before any data flows?
Before TCP can send data, both sides need to agree on starting sequence numbers. This matters because sequence numbers need to be unpredictable (for security reasons — a predictable sequence number lets attackers inject fake packets) and both sides need to know the other's starting sequence number to track ACKs correctly.
The handshake:
Client → Server: SYN (I want to connect, my starting seq is X)
Server → Client: SYN-ACK (OK, my starting seq is Y, and I acknowledge yours)
Client → Server: ACK (I acknowledge yours)
Three messages, three round trips reduced to one and a half. After this, both sides know each other's sequence numbers and the connection is established.
This is why TCP connections have a setup cost. Every new connection pays this round trip before a single byte of application data flows. For high-frequency, short-lived connections, this overhead is significant.
Why does TCP have flow control?
The sender might be faster than the receiver. If the sender floods the receiver with data faster than the receiver can process it, the receiver's buffer overflows and packets are dropped — which triggers retransmissions, making things worse.
TCP solves this with a receive window: the receiver tells the sender "I have this many bytes of buffer available." The sender limits its in-flight data to that window. As the receiver processes data and frees up buffer, it advertises a larger window. This self-regulating feedback loop prevents the sender from overwhelming the receiver.
Why does TCP have congestion control?
Flow control protects the receiver. Congestion control protects the network.
If many senders blast the network at full speed, routers get overwhelmed and drop packets. Every dropped packet triggers retransmission, which adds more traffic, which drops more packets — a death spiral called congestion collapse. This actually happened on the early internet in 1986, reducing throughput by a factor of 1000.
TCP's response: treat packet loss as a signal of network congestion. When a packet is lost, TCP assumes the network is struggling and slows down. It starts slow, grows its sending rate exponentially until it sees a loss, then backs off and grows more carefully. Different congestion control algorithms (Cubic, BBR, RENO) implement this differently, but the core idea is the same — TCP is polite to the network.
What does TCP cost you?
Reliability is not free. TCP adds:
- Latency — the 3-way handshake before data flows, retransmissions when packets are lost
- Head-of-line blocking — if packet N is lost, packets N+1, N+2... are held at the receiver waiting for N to be retransmitted, even if those later packets arrived fine. The byte stream cannot have gaps.
- State — both sides maintain connection state. This means TCP doesn't scale well to millions of very short-lived connections
These costs are why UDP exists, and why HTTP/3 later built its own reliability layer on top of UDP rather than continuing to use TCP.
The mental model
IP: sends packets, best-effort, no guarantees
TCP: wraps IP, adds:
├── Sequence numbers → detect reordering, gaps, duplicates
├── ACKs + retransmission → guarantee delivery
├── Flow control → don't overwhelm receiver
└── Congestion control → don't overwhelm network
Cost:
├── Handshake latency before data flows
├── Head-of-line blocking on loss
└── Per-connection state
TCP exists because the internet was designed to be simple and fast at the routing layer, and reliable delivery was deliberately left as a problem for the endpoints to solve. TCP is that solution — a reliability layer that every application gets for free by choosing TCP over raw IP.