You are on a video call. Someone's face freezes for a fraction of a second, a syllable drops, and then the conversation carries right on. Nobody stops to re-request the lost frame — by the time it could be resent, the moment is gone; the next frame is what matters. This is the world UDP was built for: applications that would rather lose a little data than wait for it.
UDP — the User Datagram Protocol — is the transport layer stripped to the bone. Where
UDP gives an application exactly two things over raw IP: multiplexing (ports, so the bytes reach the right program) and an optional checksum (so gross corruption can be detected). That is the entire feature list. Everything you might expect from a transport protocol, UDP deliberately omits:
Because there is no connection and no per-connection state, a UDP socket is a single mailbox that can
exchange datagrams with the whole world at once — which is exactly why one socket on port 53
can serve every DNS query on the planet. The unit UDP sends is a self-contained
datagram: unlike a TCP byte stream, message boundaries are preserved — one
send becomes one recv. That message shape is another quiet reason
applications choose it.
The whole UDP header is four 16-bit fields — eight bytes, the smallest of any mainstream transport protocol (TCP's is 20 bytes minimum). There is nothing to configure and nothing to negotiate:
| Field | Size | Meaning |
|---|---|---|
| Source port | 16 bits | Sender's port (may be 0 if no reply is expected) |
| Destination port | 16 bits | Which socket on the destination host gets the datagram |
| Length | 16 bits | Length in bytes of header + data (minimum 8) |
| Checksum | 16 bits | Error-detection over header, data, and a pseudo-header |
Eight bytes of overhead per datagram versus TCP's twenty-plus is a real saving for tiny, frequent messages — a game sending 60 position updates a second, or a DNS query that fits in a single packet. The Length field is technically redundant (IP already knows the packet size), a small historical wart. The interesting field is the last one.
The UDP (and TCP, and IP) checksum uses a charming old trick: treat the data as a sequence of 16-bit
integers, add them all up using one's-complement addition, and store the
complement (bitwise NOT) of the sum. One's-complement addition means: add normally, but
whenever the sum overflows past 16 bits, take the carry bit and add it back into the low
16 bits ("end-around carry"). The receiver adds up all the words including the
checksum; if nothing was corrupted, the result is all-ones (0xFFFF).
It's cheap enough to compute in software on every packet, and it catches all single-bit errors and most burst errors — though, being only 16 bits, it is a weak check by modern standards, not a cryptographic guarantee. The demo computes it step by step over a handful of 16-bit words:
One's-complement representation has two zeros (+0 = all-zeros, −0 =
all-ones) and, crucially, the arithmetic is endianness-friendly: you get the same checksum
whether you sum the words big-endian or little-endian, which let 1970s routers on different hardware
agree without conversion. The end-around carry is what makes the modular arithmetic work in
one's-complement — a carry out of the top is a "wrap around" that must be re-added at the bottom.
The payoff is a checksum any machine can compute and verify identically, in a few instructions per
word.
If TCP does so much more, why would a serious application pick the protocol that promises nothing? Four reasons, and every heavy UDP user is chasing at least one of them:
The classic UDP roll-call: DNS (one-shot query/response), DHCP (before you even have an IP), VoIP and video (latency > perfection), online games (freshest state wins), SNMP/NTP (tiny periodic messages), and — the plot twist — QUIC, the protocol under HTTP/3, which rebuilds reliability, ordering and congestion control on top of UDP in user space to escape TCP's limitations while keeping its guarantees. When TCP's fixed behaviour isn't the behaviour you want, you start from UDP and build your own.
"Unreliable" is a technical term here, and it trips people constantly. It does not mean UDP is flaky or that datagrams usually vanish. On a healthy local network, UDP delivers the vast majority of packets perfectly, often indistinguishably from TCP. "Unreliable" means only that UDP makes no promise: it will not detect loss, will not retransmit, will not guarantee order — so if the network drops something, UDP won't fix it for you. The correct reading is "best-effort, no guarantees," not "expect failure." And when an application does need reliability over UDP — as QUIC does — it simply adds acknowledgements, sequence numbers and timers itself, at the application layer, tuned exactly to its needs. Reliability isn't absent; it's relocated.