Five dimensions that make the difference
| Dimension | TCP | UDP |
|---|---|---|
| Connection | Connection-oriented (handshake plus state) | Connectionless; every datagram stands alone |
| Reliability | Acknowledgements, retransmission, ordered delivery | No delivery or ordering guarantee |
| Congestion control | Built in; it backs off | None — you implement it if you need it |
| Header cost | 20 bytes and up (more with options) | 8 bytes |
| Latency behaviour | Waits for retransmission; jitter on loss | No waiting; low jitter but data may vanish |
When UDP is the right pick
- Live audio and video: late packets are worthless — better dropped than awaited;
- Gaming: state updates constantly; the newest frame beats replaying an old one;
- Short queries: DNS, for example — one round trip, and retries are simpler at the application layer;
- Custom transports: QUIC rebuilds a modern transport on top of UDP.
When TCP is mandatory
- Files, databases, messages: anything where not a single byte may go missing;
- Strict ordering required: log streams, replication channels;
- You do not want to build a transport: retransmission, congestion control and framing are hard — use what exists.
Four things to rebuild on UDP
- Sequence numbers: to detect loss and reordering;
- A retransmission policy: when to retry and when to give up;
- Congestion control: otherwise you saturate weak links and hurt everything else;
- Sizing and MTU: oversized datagrams get fragmented at the IP layer, where losing one fragment kills the whole packet.
An often-forgotten detail: message boundaries
TCP is a byte stream with no message boundaries: data from several sends may be merged or split, so the application must frame it with length prefixes, delimiters or fixed structures. UDP preserves datagram boundaries — one send, one receive — which also means every datagram must stand alone rather than relying on neighbours.
Common misconceptions
- "UDP loses packets, so it is unusable": wrong — what matters is whether the application tolerates loss and how you compensate;
- "UDP is always faster": not necessarily. You save handshake and head-of-line blocking, but re-implementing retransmission often ends up worse than TCP;
- "TCP never loses data": TCP recovers lost segments; the application can still time out, and the timeout depends on retransmission behaviour.
How this relates to HTTP/3
HTTP/3 runs on QUIC, and QUIC runs on UDP. The goal is not "no reliability" — it is putting retransmission, congestion control and TLS in one layer, keeping reliable delivery while avoiding TCP's head-of-line blocking: one lost packet no longer stalls every stream.
Common questions
Which for internal RPC? Use TCP (or HTTP/2, or gRPC) unless you have real transport-layer experience. What happens to a real-time game over TCP? Retransmission waits make controls feel sticky — that is exactly why they choose UDP. How do I measure UDP quality? Track loss, jitter and reordering — not just bandwidth.
Which application protocols run on UDP
- DNS: UDP 53 by default, falling back to TCP 53 for large or reliability-sensitive answers — a common cause of "some lookups are slow";
- QUIC / HTTP3: reliability and congestion control reimplemented over UDP, so UDP 443 must be allowed;
- Real-time audio and video: RTP rides UDP — dropping a frame beats retransmitting it, since added latency hurts more than loss;
- VPNs and tunnels: WireGuard uses UDP, and some networks throttle or block UDP outright.
Notes on moving to QUIC
- Confirm middleboxes allow UDP 443 and keep an HTTP/2 fallback for clients that are blocked;
- Connection migration relies on connection IDs, so tune keep-alives when NAT timeouts are short;
- Monitor the fallback rate and handshake failure rate — the two best signals of real-world availability.
Three questions when choosing
First, must a lost packet be retransmitted? If so, use TCP. Second, can you afford connection setup? For many small requests, connection reuse matters more than the protocol. Third, will middleboxes block it? UDP is restricted on some corporate networks, so design a TCP fallback.