System Design
TCP vs UDP
Two protocols carry almost all internet traffic, and they make opposite trade-offs. TCP guarantees delivery; UDP races ahead without looking back. Knowing which to choose - and why - is a system design fundamental.
Almost everything that moves across the internet rides on one of two transport protocols: TCP or UDP. They sit at the same layer and do the same broad job - carrying data between two machines - but they make opposite trade-offs. TCP is careful and reliable: it guarantees your data arrives complete and in order, no matter what. UDP is fast and carefree: it fires data off without checking whether it arrives. Neither is "better" - they're tools for different jobs, and knowing which to choose, and why, is a genuine system design fundamental.
This guide lays out both, the trade-off between them, and how to decide.
TCP: reliable and ordered
TCP (Transmission Control Protocol) is connection-oriented and reliable. Before sending data, TCP establishes a connection between the two machines (a handshake), and then guarantees that all data arrives, complete and in the correct order. If a packet is lost in transit, TCP detects it and retransmits it. If packets arrive out of order, TCP reorders them. The receiving application gets exactly the data that was sent, in order, with nothing missing.
To deliver these guarantees, TCP does real work:
- Connection setup (handshake). TCP starts with a three-way handshake to establish the connection before any data flows - a brief back-and-forth that confirms both sides are ready.
- Acknowledgments and retransmission. The receiver acknowledges received data; if the sender doesn't get an acknowledgment, it retransmits. This is how TCP guarantees delivery.
- Ordering. TCP numbers the data so the receiver can reassemble it in the correct order even if packets arrive scrambled.
- Flow and congestion control. TCP adjusts its sending rate to avoid overwhelming the receiver or the network, backing off when the network is congested.
All this machinery makes TCP reliable - but it adds overhead and latency (the handshake, the acknowledgments, the retransmissions, the waiting for out-of-order packets). TCP trades some speed for the guarantee that your data arrives intact.
UDP: fast and connectionless
UDP (User Datagram Protocol) is connectionless and unreliable (in the technical sense - it makes no delivery guarantees). It just sends data - packets called datagrams - to the destination without establishing a connection, without acknowledgments, without retransmission, and without ordering. Fire and forget. If a packet is lost, it's lost; UDP doesn't notice or care. If packets arrive out of order, UDP delivers them as they come.
This sounds worse, but it's the point: by skipping all of TCP's machinery, UDP is fast and has low overhead. There's no handshake delay, no waiting for acknowledgments, no retransmission stalls, no reordering. Data goes out immediately and arrives as fast as the network allows. UDP trades reliability for speed and simplicity.
sequenceDiagram
participant A as Sender
participant B as Receiver
Note over A,B: TCP - connection + acknowledgments
A->>B: SYN (let's connect)
B-->>A: SYN-ACK
A->>B: ACK (connected)
A->>B: Data
B-->>A: ACK (got it)
Note over A,B: UDP - just send, no setup, no ack
A->>B: Datagram
A->>B: Datagram
A->>B: Datagram
This sequence diagram contrasts TCP and UDP. TCP begins with a three-way handshake: the sender sends SYN, the receiver replies SYN-ACK, the sender replies ACK, and only then is the connection established. Data is sent and acknowledged. UDP, by contrast, has no setup and no acknowledgments - the sender simply fires off datagrams one after another without establishing a connection or confirming receipt. TCP's extra steps provide reliability; UDP's absence of them provides speed.
The core trade-off
The whole comparison comes down to one trade-off: reliability versus speed and overhead.
TCP gives you reliability and ordering at the cost of overhead and latency. UDP gives you speed and low overhead at the cost of reliability. Everything else follows from this. TCP is the right default when your data must arrive correctly and completely - losing or scrambling it would break things. UDP is the right choice when speed matters more than perfection, and the occasional lost packet is acceptable or can be handled by the application.
| TCP | UDP | |
|---|---|---|
| Connection | Connection-oriented (handshake) | Connectionless (no setup) |
| Reliability | Guaranteed delivery (retransmits lost data) | No guarantee (lost packets stay lost) |
| Ordering | In-order delivery | No ordering |
| Speed / overhead | Slower, more overhead | Faster, low overhead |
| Error handling | Built-in (acks, retransmission) | None (up to the application) |
| Best for | Data that must arrive intact | Speed-critical, loss-tolerant data |
When to use TCP
Use TCP when correctness and completeness matter more than raw speed - which is most things:
- Web browsing (HTTP/HTTPS). A web page must arrive complete and correct; a missing chunk breaks it. (Traditionally over TCP.)
- Email. Messages must arrive intact and in order.
- File transfers. A downloaded file must be exactly correct - a single lost piece corrupts it.
- APIs and database connections. Requests and responses must arrive reliably and completely.
The pattern: anything where missing or scrambled data is unacceptable uses TCP. The reliability is worth the overhead, and for most applications the latency cost is negligible.
When to use UDP
Use UDP when speed and low latency matter more than perfect delivery, and occasional loss is tolerable:
- Live video and voice (streaming, calls). If a packet is lost in a live call, you don't want to stop and retransmit it - by the time it arrived, that moment of audio would be stale. Better to skip it and keep going. A tiny glitch beats a stall.
- Online gaming. Real-time game state needs to be as current as possible; a lost position update is better skipped than retransmitted late.
- DNS lookups. A DNS query is small and fast; UDP's low overhead suits it (and it retries if needed).
- Real-time telemetry and streaming. High-volume, time-sensitive data where speed beats guaranteed delivery.
The pattern: real-time data where fresh matters more than complete, and a late packet is worse than a missing one. UDP's speed is the priority, and applications that need some reliability can build just what they need on top of UDP rather than paying for all of TCP's guarantees.
The three-way handshake in detail
TCP's reliability starts with how it opens a connection - the three-way handshake - worth understanding because it's a classic interview topic and it explains part of TCP's overhead.
To establish a connection, three messages are exchanged:
- SYN - the client sends a SYN ("synchronize"), saying "I want to start a connection, here's my starting sequence number."
- SYN-ACK - the server replies with SYN-ACK, acknowledging the client's request and sending its own SYN ("I'm ready, here's my sequence number, and I acknowledge yours").
- ACK - the client sends an ACK acknowledging the server's, and the connection is established.
After these three steps, both sides have agreed to communicate and synchronized their sequence numbers (which TCP uses to order data and detect loss). Only then does data flow. This handshake is what makes TCP "connection-oriented" - there's a real setup before any data moves - and it's part of TCP's overhead: that initial round-trip adds latency before the first byte of actual data is sent. For a single quick request this overhead is small but real, which is one reason very latency-sensitive applications sometimes prefer UDP (no handshake) or newer protocols that reduce setup cost.
Head-of-line blocking: a subtle TCP cost
A more subtle TCP characteristic: head-of-line blocking. Because TCP guarantees in-order delivery, if one packet is lost, everything behind it has to wait until that packet is retransmitted and arrives - even if the later packets already made it. The receiver can't deliver the later data to the application until the missing earlier piece is filled in, because that would violate ordering. So one lost packet can stall a whole stream behind it.
This is usually fine, but for some workloads it's a real drawback - it's part of why protocols carrying many independent streams over one TCP connection can suffer (a loss in one stream blocks the others), and it's one of the problems the newest web protocols address by building on UDP instead, where independent streams don't block each other. Understanding head-of-line blocking explains a class of performance issues and why "reliability through strict ordering" has a cost beyond just the retransmission.
Building reliability on UDP
A common point of confusion: "if UDP is unreliable, how can it be used for anything important?" The answer is that applications using UDP can add exactly the reliability they need on top, rather than accepting TCP's full, one-size-fits-all guarantees.
A real-time application might add lightweight acknowledgments for the few messages that truly must arrive, while letting the rest flow fire-and-forget. A game might resend critical state but skip routine position updates (since a newer update arrives momentarily anyway). This selective, application-controlled reliability is more efficient than TCP for these cases, because TCP would insist on reliably delivering everything in order - including data that's already stale by the time it's retransmitted. By starting from UDP's bare, fast transport and adding only the guarantees they need, applications get a custom balance TCP can't offer. So "UDP is unreliable" doesn't mean "UDP can't be used for important things" - it means the application decides what reliability to add, rather than the protocol forcing it.
Why TCP is the sensible default
Given UDP's speed, you might wonder why TCP is the default for most things rather than the exception. The reason is that most applications genuinely need reliability and order, and for them TCP's overhead is negligible while its guarantees are essential. When you load a web page, fetch an API response, or download a file, you need every byte to arrive correctly and in order - a missing or scrambled piece would corrupt the result. The handshake and acknowledgment overhead costs a few milliseconds, imperceptible against the value of guaranteed correctness. So TCP is the default because correctness-with-small-overhead is the right trade for the majority of applications.
UDP is the deliberate exception, chosen specifically when the overhead of guaranteed, ordered delivery would actively hurt - real-time scenarios where a late-but-complete delivery is worse than a fast-but-occasionally-lossy one. The mental model: reach for TCP by default, and switch to UDP only when you have a specific reason that low latency and freshness matter more than perfect delivery. This is why the vast majority of internet traffic is TCP, with UDP carrying the specific real-time and low-overhead cases where its trade-off wins.
A concrete contrast
To cement the difference, picture the same lost packet in two scenarios. In a file download over TCP, a lost packet is detected and retransmitted; you wait a moment longer, but the file arrives perfect. That's exactly what you want - you'd rather wait than get a corrupted file. Now picture a lost packet in a live voice call over UDP: that packet held a few milliseconds of audio. Retransmitting it would be pointless - by the time it arrived, the conversation has moved on, and inserting stale audio would be worse than a tiny glitch. So UDP just drops it and continues, and you hear a momentary blip rather than a stall. Same event - a lost packet - and the right response is opposite in each case. That's the entire TCP-versus-UDP decision in one image: does your data need to be made whole even at the cost of delay (TCP), or stay timely even at the cost of occasional loss (UDP)?
Where they sit, and what runs on each
To place TCP and UDP in the bigger picture: both are transport-layer protocols, sitting on top of IP (which handles addressing and routing of packets across networks) and underneath the application protocols that actually do useful work. So the layering is: applications speak protocols like HTTP, which run on top of TCP or UDP, which run on top of IP. TCP and UDP are the layer that turns IP's basic packet delivery into something applications can use - either reliably (TCP) or fast (UDP).
Knowing what runs on each clarifies the division. On TCP: HTTP/HTTPS (traditionally), email protocols, file transfer, secure shell, database connections - the protocols where correctness is essential. On UDP: DNS queries, real-time voice and video, online gaming, and streaming protocols - where speed and low overhead matter. This mapping isn't arbitrary; each application protocol was built on the transport that fits its needs. When you learn that a given protocol runs on TCP or UDP, you can immediately infer something about its priorities: TCP-based means it values guaranteed correct delivery, UDP-based means it values speed and tolerates some loss. The choice of transport is a window into what the protocol cares about - which is the same reasoning you apply when designing your own systems.
A note on the bigger picture
It's worth knowing the line between them has blurred at the edges. Some modern protocols build reliability features on top of UDP to get the best of both - UDP's speed and flexibility plus custom reliability where needed (the newest version of the web's protocol does exactly this). And applications using UDP often add their own lightweight reliability for the specific guarantees they want, rather than accepting TCP's full machinery. But the fundamental distinction stands: TCP gives you reliability built in; UDP gives you a fast, bare-bones transport you can build on. Choosing between them - or building on UDP when you need a custom balance - starts with understanding the core trade-off.
Interview: TCP versus UDP is a classic system design and networking question. The strong answer isn't reciting features - it's the trade-off: TCP is reliable and ordered but has overhead; UDP is fast and low-overhead but unreliable. Then apply it: "I'd use TCP for the API because requests must arrive correctly," or "I'd use UDP for the live video stream because low latency matters more than a perfect packet, and a late retransmission would be useless." Showing you choose based on whether the data needs guaranteed delivery or speed-with-tolerable-loss is exactly the reasoning interviewers want.
The bottom line
TCP and UDP carry almost all internet traffic and make opposite trade-offs. TCP is connection-oriented and reliable - it establishes a connection, guarantees delivery (retransmitting lost data), and maintains order, at the cost of overhead and latency. UDP is connectionless and unreliable - it fires off datagrams with no setup, acknowledgment, retransmission, or ordering, gaining speed and low overhead. The core trade-off is reliability versus speed: use TCP when data must arrive complete and correct (web, email, files, APIs), and UDP when speed beats perfection and some loss is fine (live video and voice, gaming, DNS, real-time data).
Choose based on whether your data needs guaranteed delivery or low-latency speed, and you'll pick the right protocol every time. We cover transport protocols and networking across System Design Fundamentals.
Go deeper
- Transmission Control Protocol (Wikipedia) - TCP's mechanisms in detail.
- User Datagram Protocol (Wikipedia) - UDP's design and uses.
- MDN - TCP - a concise developer-oriented overview.
- The System Design Primer - TCP and UDP in a system design context.