Engineering Notes
Home/Networking & Web/Fundamentals/TCP vs UDP
Networking & Web · Fundamentals

TCP vs UDP

TCP gives you a reliable, ordered byte stream at the cost of handshakes and head-of-line blocking; UDP gives you fast, independent datagrams and leaves the rest to you. Watch both handle a lost packet.

🌐 Networking & Web● Beginner⏱ 7 min read▶ 2 interactive🛠️ 2 exercises🎤 5 interview Q&As

🎯 What you'll learn

  • What the transport layer does
  • TCP: handshake, acknowledgements, retransmission, flow/congestion control
  • UDP: datagrams with no guarantees
  • Where each is used (and why QUIC builds on UDP)

📚 Before you start

1Two Transport-Layer Protocols, One Job: Deliver Data Between Processes

Both TCP and UDP sit at the transport layer (see the TCP/IP model topic), and both do the same basic addressing job: get data from a process on one host to a process on another, using ports to identify which process (their own topic). Beyond that, they make opposite tradeoffs.

TCPUDP
Full nameTransmission Control ProtocolUser Datagram Protocol
ConnectionConnection-oriented — handshake required before data flowsConnectionless — just send
ReliabilityGuaranteed delivery, retransmits lost dataNo guarantees — lost data stays lost
OrderingGuaranteed in-order deliveryNo ordering guarantee
DuplicationGuaranteed no duplicatesDuplicates possible
Flow controlYes (sliding window)No
Congestion controlYes (slows down under network congestion)No
Header overhead20 bytes minimum8 bytes
Speed / latencySlower to start (handshake), overhead per packetFaster — no setup, minimal overhead
Typical usesHTTP/1.1, HTTP/2, TLS, file transfer, databases, emailDNS, video/voice calls, live streaming, gaming, HTTP/3 (QUIC, over UDP)

2Why Both Still Exist

It's tempting to think TCP is strictly "better" since it adds guarantees UDP lacks — but those guarantees cost time and bandwidth. If a video call drops one frame, retransmitting it arrives too late to be useful anyway — the call should just keep going with the next frame (UDP's model). If a bank transfer drops one byte, that's unacceptable — it must be retransmitted and delivered correctly no matter the cost (TCP's model). The choice between them is a real engineering tradeoff based on whether correctness or timeliness matters more for a given use case.

3Where Each Is Actually Used

  • TCP: virtually all web traffic through HTTP/1.1 and HTTP/2, TLS handshakes, SSH, database connections (Postgres, MySQL), email (SMTP/IMAP) — anywhere silently losing or reordering bytes would corrupt the application's data.
  • UDP: DNS queries (a single small request/response — cheaper to just retry than to hold a connection open), VoIP and video calls (a late packet is worse than a dropped one), online gaming (same reasoning), and increasingly HTTP/3, which is built on QUIC — a protocol that runs over UDP but reimplements TCP-like reliability in user space to avoid some of TCP's specific limitations (this is covered in the HTTP versions topic).
Under the HoodHow it works internally▾

The TCP three-way handshake — the actual mechanics

TCP three-way handshake: SYN, SYN-ACK, ACK exchanging sequence numbers before data flows
TCP three-way handshake: SYN, SYN-ACK, ACK exchanging sequence numbers before data flows

Before any data flows, TCP performs a handshake to synchronize both sides' sequence numbers — the counters each side uses to track exactly which bytes have been sent and received:

  1. SYN: the client picks a random initial sequence number x and sends a segment with the SYN flag set and seq=x. This says "I want to open a connection, and my byte stream starts counting from x."
  2. SYN-ACK: the server picks its own random initial sequence number y, and replies with both SYN and ACK flags set: seq=y, ack=x+1. The ack=x+1 acknowledges it received the client's SYN (the "+1" is because a SYN itself consumes one sequence number); the seq=y starts the server's own byte counting.
  3. ACK: the client replies with ACK, ack=y+1, acknowledging the server's SYN. No SYN flag this time — the handshake is over.

After this exchange, both sides know the other's starting sequence number, and both have confirmed the network path works in both directions before a single byte of actual application data has been sent. This is real cost — an extra full round trip before any data flows — which is exactly why TCP connection reuse (keep-alive) and TLS session resumption exist: to avoid repeating this cost on every request.

How TCP achieves reliability, concretely

  • Sequence numbers: every byte TCP sends is numbered. The receiver can detect exactly which bytes it has and hasn't received, and reassemble out-of-order segments into the correct order using these numbers — this is the actual mechanism behind "guaranteed ordering," not magic.
  • Acknowledgments (ACKs): the receiver continuously tells the sender the sequence number of the next byte it expects. If the sender doesn't receive an ACK for data within a timeout (or receives duplicate ACKs signaling a gap), it concludes that data was lost.
  • Retransmission: on a missing/timed-out ACK, TCP resends the unacknowledged data. This is the actual mechanism behind "guaranteed delivery" — it's not that packets can't be lost on the wire (they still can, IP is still best-effort underneath), it's that TCP detects the loss and resends until it's confirmed received.
  • Sliding window flow control: the receiver advertises a "window size" — how many unacknowledged bytes it's currently willing to buffer. The sender must not send more than that before getting an ACK. This prevents a fast sender from overwhelming a slow receiver's buffer, and the window slides forward as ACKs arrive, allowing more data to be sent.
  • Congestion control: separately from flow control (which protects the receiver), TCP also tracks network congestion (protecting the network path) via algorithms like slow start and congestion avoidance, ramping the send rate up gradually and backing off sharply on detected loss.

What UDP genuinely does not have

UDP is not "TCP with fewer features enabled" — it structurally lacks all of the above. A UDP datagram is sent with an 8-byte header (source port, destination port, length, checksum) and nothing more:

  • No handshake — the very first datagram sent can contain application data immediately.
  • No sequence numbers in the UDP header itself — if datagrams arrive out of order, out of order is exactly how the application receives them, unless the application layer adds its own sequencing (which real-time protocols like RTP do, entirely at the application layer, not inside UDP).
  • No ACKs, no retransmission — a dropped datagram is gone; UDP never notices and never resends it.
  • No flow or congestion control — a UDP sender can blast datagrams as fast as the application asks, with no built-in backpressure; this is also why misbehaving UDP applications can be more dangerous to shared network links than misbehaving TCP applications, which self-throttle under congestion.

This is precisely why protocols that need TCP-like reliability but want more control than TCP gives (like QUIC, underlying HTTP/3) build their own reliability layer on top of UDP in user-space code, rather than using raw UDP directly — they want UDP's lack of head-of-line blocking at the OS/kernel level, while still implementing their own sequencing and retransmission logic tailored to their needs.

⚠️ Common Pitfalls

  1. Assuming UDP is "unreliable" in the sense of "broken" — it's reliable in the sense that it correctly does exactly what it promises (best-effort delivery, no more); it's a deliberate design choice, not a defect.
  2. Assuming TCP guarantees data arrives, period — TCP guarantees that if the connection completes normally, delivered data arrived correctly and in order; it cannot guarantee delivery if the connection is abruptly killed (e.g., cable unplugged) — the application layer must still handle that failure mode.
  3. Forgetting the handshake cost is a real, measurable latency hit — one extra round trip before data flows matters a lot for short-lived, latency-sensitive connections (this is a major part of why HTTP/2 pushed connection reuse, and why HTTP/3 moved to QUIC/UDP to reduce handshake round trips further — see the HTTP versions topic).
  4. Believing flow control and congestion control are the same mechanism — flow control protects the receiver's buffer; congestion control protects the shared network path; TCP runs both, independently.
  5. Thinking UDP can't be reliable at all — reliability can be built on top of UDP at the application layer (as QUIC/HTTP-3 and RTP do); UDP itself just doesn't provide it for free.

📋 Quick Reference

text
TCP: connection-oriented, reliable, ordered, flow+congestion controlled, higher overhead
     3-way handshake: SYN → SYN-ACK → ACK
     reliability = sequence numbers + ACKs + retransmission + sliding window

UDP: connectionless, best-effort, no ordering, no flow/congestion control, minimal overhead
     no handshake — first datagram can carry data immediately

Use TCP when correctness > timeliness (web, DB, file transfer, TLS)
Use UDP when timeliness > correctness (voice/video, gaming, DNS, QUIC/HTTP-3)

🧠 Key takeaways

  • TCP: connection-oriented, reliable, ordered, flow + congestion control; costs a handshake and HOL blocking.
  • UDP: connectionless datagrams, no guarantees, minimal overhead.
  • TCP for web/APIs/databases; UDP for DNS, real-time media, games and QUIC/HTTP/3.
  • Choose by whether late data is worse than lost data.

🎤 Interview Q&A

Questions interviewers ask about this topic. Answer out loud first, then open a card to compare.

Q1Compare TCP and UDP.core▾

TCP: connection-oriented, reliable, ordered byte stream with retransmissions, flow control and congestion control; higher latency/overhead. UDP: connectionless datagrams, no delivery or order guarantees, minimal overhead. Use TCP for web, APIs, databases; UDP for DNS, video calls, gaming, and QUIC.

Follow-ups interviewers ask
  • Why does real-time video prefer UDP? A late packet is useless; retransmission would add delay.
Q2Explain the TCP three-way handshake and teardown.core▾

SYN (client, initial sequence number) → SYN-ACK (server) → ACK (client); then data flows. Teardown: FIN/ACK in each direction. The side that closes first enters TIME_WAIT for ~2×MSL to catch late packets.

Follow-ups interviewers ask
  • Why does TIME_WAIT matter for servers? Many short connections can exhaust ephemeral ports; reuse connections (keep-alive, pooling).
Q3What's head-of-line blocking in TCP?core▾

TCP delivers bytes in order, so a single lost packet blocks delivery of all later data until it's retransmitted, even if it belongs to independent streams (as in HTTP/2 multiplexing). QUIC fixes this with independent streams over UDP.

Follow-ups interviewers ask
  • Does HTTP/2 remove HOL blocking? At the HTTP level yes, at the TCP level no.
Q4What are flow control and congestion control?senior▾

Flow control (receive window) stops the sender from overwhelming the receiver. Congestion control (slow start, AIMD, CUBIC, BBR) adapts the sending rate to network capacity to avoid congestion collapse.

Follow-ups interviewers ask
  • What's slow start? Starting with a small window and doubling per RTT until loss or threshold.
Q5How would you build reliability on top of UDP?core▾

Add sequence numbers, acknowledgements, retransmission with timeouts, and optionally ordering and congestion control, as QUIC does. Often you only need partial reliability (e.g. resend important game state, not every position update).

Follow-ups interviewers ask
  • Example protocol? QUIC, and game networking libraries.

🛠️ Practice exercises

Each exercise is a file in this topic folder. Code exercises are self-checking: run them and make the checks pass.

✅ Check yourself

Answer the questions — feedback is instant.

1. Why does a lost TCP segment delay later segments?
The stream must stay ordered.
2. Which protocol does DNS mostly use?
Small request/response.
3. Why is HTTP/3 built on UDP?
QUIC.
4. How many RTTs does the TCP handshake cost before data?
SYN/SYN-ACK, then data with the ACK.