5 min read

Q02 — Why does UDP exist — when is "unreliable" actually the right choice?


Why would anyone want an unreliable protocol?

After reading about TCP, it seems like reliability is always better. Why would you ever choose a protocol that can lose your data?

The answer is that TCP's reliability mechanisms cost time — and for some applications, time is more valuable than completeness.

Think about a video call. You're receiving 30 frames per second. Each frame is a snapshot of the world at a specific moment. If frame 47 is lost in transit, TCP will:

  1. Notice the loss (timeout or duplicate ACK)
  2. Retransmit frame 47
  3. Hold frames 48, 49, 50... at the receiver, waiting for frame 47 to arrive before delivering them in order

By the time frame 47 is retransmitted and received, 100–300ms may have passed. The video player was waiting the whole time. When it finally gets frame 47, frames 48 through 55 are already stale. The user sees a freeze followed by a jump.

Worse: frame 47 is now useless. It showed the world 100ms ago. Nobody wants to see where your face was 100ms ago — they want to see where your face is right now. The retransmitted frame is correct but irrelevant.

TCP's guarantee — "you will receive this data, in order, no matter what" — is actively harmful here. The application would rather skip the lost frame and keep moving.


What does UDP actually do?

UDP (User Datagram Protocol) is almost nothing. It takes your data, wraps it in a packet with a source port, destination port, length, and checksum, and sends it. That's it.

No handshake. No sequence numbers. No ACKs. No retransmission. No flow control. No congestion control.

The sender fires and forgets. The receiver gets what it gets. If a packet is lost, nobody tells anyone. If packets arrive out of order, UDP delivers them out of order. If the same packet arrives twice, the application gets it twice.

UDP is fast because it does none of the bookkeeping TCP does. There is no per-connection state. There is no setup latency. A UDP packet goes out immediately and the sender moves on.


So what kind of applications actually want this?

The key insight is: UDP is not for applications that don't care about reliability. It's for applications that handle reliability differently — or don't need it at all.

Real-time media (video/audio calls, live streaming): As explained above — stale data is worse than no data. The application implements its own strategy: interpolate a missing frame, use the previous audio sample, skip ahead. These strategies are domain-specific and much smarter than TCP's blind retransmit.

Online gaming: When you're playing a fast-paced game, the server is broadcasting player positions many times per second. If a position update is lost, the next update (arriving milliseconds later) supersedes it anyway. A retransmitted position from 80ms ago would cause the player's character to stutter backward. Games drop stale packets and apply prediction/interpolation instead.

DNS: A DNS query is a tiny request expecting a tiny response. If the response is lost, the client simply re-sends the query — there is no need for a persistent connection or handshake. TCP's overhead would dwarf the actual query. UDP makes DNS fast for the common case; the application retries if needed.

Tunneling and custom protocols (VPNs, QUIC): Sometimes you want to build your own reliability layer with different trade-offs than TCP's. You can't run TCP inside TCP efficiently (TCP's congestion control breaks when it runs over another TCP connection), but you can build a smarter transport on top of UDP. QUIC — the protocol under HTTP/3 — does exactly this.


Why can't these applications just use TCP and ignore some packets?

You can't "ignore" packets in TCP. TCP is a byte stream — it delivers bytes in order, and it will not deliver byte N+1 until byte N has arrived. There is no API to say "skip this lost segment and give me what came after it." You either get everything in order, or you wait.

This is called head-of-line blocking. Even if all subsequent packets have arrived and are sitting in the receive buffer, TCP holds them hostage until the missing packet is retransmitted. UDP has no such concept — each datagram is independent, so a lost datagram doesn't block the ones that followed it.


What does "unreliable" actually mean in practice?

UDP is unreliable in a controlled sense. On most modern networks, packet loss is low — a few percent at worst, often much less. UDP is not "data just disappears randomly all the time." It's "we don't add a recovery mechanism, so rare losses are unrecovered."

For a video call at 30fps, losing 1-2% of frames means the application's interpolation handles it invisibly. For a game sending 60 position updates per second, a lost update is covered by the next one 16ms later. The unreliability is tolerable — and avoiding TCP's overhead is worth it.


When is UDP the wrong choice?

Any time your application needs every byte, in order, and cannot make forward progress without it: file transfers, database queries, email, web pages, API calls. These applications need TCP. Losing even one byte corrupts the result, and "just retry" means you need a reliability layer — which is what TCP already is.

The mistake engineers make is reaching for UDP because they've heard it's "faster," then rebuilding a broken version of TCP on top of it. If you need reliability and ordering, use TCP. If you need low-latency delivery of data where stale is worse than absent, use UDP.


The mental model

code
TCP:  reliable, ordered, complete — at the cost of latency and head-of-line blocking
UDP:  fast, independent datagrams — at the cost of no delivery guarantee

Choose UDP when:
  ├── Latency matters more than completeness (real-time media, gaming)
  ├── Stale data is useless (position updates, video frames)
  ├── Request-response is tiny and retry is trivial (DNS)
  └── You're building your own transport layer (QUIC, VPNs)

Choose TCP when:
  └── Every byte matters and you can't tolerate gaps (everything else)

UDP exists because TCP's guarantees are not always what you want. Reliability is a policy choice, not a universal good — and UDP lets the application decide its own policy.