TCP vs UDP
Every time data moves across a network, something has to decide how it gets there. Two protocols dominate that job at the transport layer: TCP and UDP. They take opposite approaches — one guarantees delivery at the cost of speed, the other optimises for speed and accepts the occasional loss. Choosing the right one matters enormously for the systems you build.
TCP vs UDP — Packet Flow
TCP
Client
Server
UDP
Client
Server
TCP — Reliable, Ordered, Connection-Based
TCP stands for Transmission Control Protocol. It was designed with one core goal: make sure data arrives completely and in the right order, no matter what.
Before any data is sent, TCP establishes a connection. Every packet sent is acknowledged by the receiver. If an acknowledgement does not arrive within a timeout window, the sender retransmits the packet. Packets that arrive out of order are held in a buffer and resequenced before being handed to the application. The receiving end signals how much data it can handle, and the sender respects that limit — this is called flow control. When the network is congested, TCP backs off and reduces its transmission rate through congestion control algorithms.
All of this comes at a cost. There is overhead in establishing the connection. There is latency added by waiting for acknowledgements. A single lost packet can stall the entire stream while retransmission happens.
The tradeoff is worth it any time data integrity is non-negotiable.
The Three-Way Handshake
Before TCP sends a single byte of real data, it runs a handshake to establish the connection and synchronise sequence numbers on both sides:
Client → SYN → Server
Client ← SYN-ACK ← Server
Client → ACK → Server
[connection established]
SYN (synchronise): the client picks a random starting sequence number and says "I want to connect, my sequence starts at X."
SYN-ACK: the server acknowledges the client's sequence number (X+1) and sends its own starting sequence number Y.
ACK: the client acknowledges the server's sequence number (Y+1). Both sides now know each other's sequence numbers. They can detect out-of-order or missing packets for the rest of the session.
This handshake adds one full round-trip before any application data flows. On a 100ms latency connection, that is 100ms of setup before a byte of payload is sent. It matters — and it is why QUIC (discussed below) exists.
UDP — Fast, Connectionless, No Guarantees
UDP stands for User Datagram Protocol. It does the opposite of almost everything TCP does.
There is no handshake. The sender fires packets at the receiver without first confirming the receiver is ready. There is no acknowledgement — the sender has no idea whether packets arrived. There is no retransmission if they do not. Packets can arrive out of order and UDP does nothing to fix that. Packets can be lost entirely and UDP does not notice.
What UDP does offer is minimal overhead and extremely low latency. A UDP packet is just a payload with a small header. No connection state to maintain. No acknowledgement round-trips. No retransmission delays.
Some packets will be lost. In many applications, that is an acceptable tradeoff.
When to Use TCP
Use TCP any time losing or corrupting data would break the application:
- HTTP and HTTPS — a web page with missing bytes is broken
- Email (SMTP, IMAP) — a message with missing paragraphs is unusable
- File transfer (FTP, SCP) — a file with missing bytes is corrupted
- Database connections — a query with missing bytes produces wrong results
- SSH — a terminal session with missing commands is dangerous
The rule of thumb: if you would not accept data loss, use TCP.
When to Use UDP
Use UDP when speed matters more than perfection, and the application can tolerate some loss:
- Video streaming — a dropped frame produces a brief glitch, a retransmission delay produces a freeze. The glitch is preferable.
- Online gaming — your position 200ms ago is useless. A retransmitted stale packet is worse than no packet.
- VoIP and voice calls — a missing 20ms of audio is heard as a tiny crackle. Waiting for retransmission produces a half-second gap.
- DNS queries — a small request/response that fits in a single packet. If it is lost, the client simply retries. No need for TCP's handshake overhead.
- Live broadcasts — thousands of simultaneous viewers cannot all trigger retransmissions; staying live is more important than perfect frames.
The rule of thumb: if you can handle loss, and freshness matters more than completeness, use UDP.
TCP Head-of-Line Blocking
TCP has a subtle but significant problem called head-of-line blocking. Because TCP guarantees in-order delivery, if one packet in a stream is lost, TCP holds back all the packets that arrived after it — even the ones that arrived fine — until the missing packet is retransmitted and received.
This is fine for a single sequential data stream. It becomes a serious problem when you multiplex multiple independent streams over a single TCP connection, as HTTP/2 does. If one HTTP/2 stream loses a packet, all the other streams on that connection are stalled waiting for TCP to recover the missing packet. A missing packet in one image's stream can block JavaScript from loading.
HTTP/2's multiplexing was designed to solve HTTP/1's head-of-line blocking at the HTTP layer. TCP introduced a new head-of-line blocking problem at the transport layer.
QUIC — The Best of Both
QUIC is a transport protocol developed by Google and now the basis of HTTP/3. It runs on top of UDP but implements reliability, ordering, and encryption at the application layer.
Because QUIC is built on UDP, it sidesteps TCP's head-of-line blocking entirely. Each stream within a QUIC connection is independent — a lost packet in one stream does not block the others.
QUIC also dramatically reduces connection setup latency. TCP requires a handshake before any data flows. TLS adds more round trips on top. QUIC combines its transport handshake with TLS 1.3 negotiation, reducing setup to a single round trip — or zero round trips for repeat connections (0-RTT), where the client can send data before the handshake completes.
Where QUIC appears in the real world:
- HTTP/3 (used by Cloudflare, Google, Meta) runs on QUIC
- WebRTC uses UDP for its media channels
- Gaming engines often use UDP with custom reliability layers that look a lot like QUIC
QUIC represents the industry's conclusion that the right answer is not TCP or UDP in their raw forms, but purpose-built protocols that use UDP as a foundation and implement only the reliability they actually need.
Key Takeaways
- TCP guarantees delivery, order, and integrity through acknowledgements, retransmission, and sequencing — at the cost of latency and overhead
- UDP fires packets without handshakes or acknowledgements — extremely fast but no delivery guarantee
- The three-way handshake establishes sequence numbers before any data flows, adding one round-trip of latency to every TCP connection
- Use TCP for anything where data loss or corruption would break the application: web, email, databases, file transfer
- Use UDP for anything where freshness beats completeness: video calls, gaming, DNS, live streaming
- TCP's head-of-line blocking is a real performance problem for multiplexed connections — HTTP/2 moved blocking from the HTTP layer to the TCP layer
- QUIC solves both: built on UDP, it adds per-stream reliability without global blocking, and merges transport + TLS handshakes for faster connection setup
Next up: the OSI Model — the seven-layer framework that places TCP, UDP, IP, and everything else into a coherent architecture.
Enjoyed this breakdown?
Get new lessons in your inbox.