TCP gets heavier the more you talk about it, while UDP is often reduced to “connectionless, unreliable”. That is not wrong, but it is too thin. What really matters in engineering is not which features UDP lacks, but why it deliberately does not do them, and what gets pushed back onto the application or a higher-layer protocol when it does not.
DNS, DHCP, real-time audio/video, game protocols, and QUIC all sit on top of UDP, but they are clearly not the same semantic thing. That is exactly the point: UDP does not provide a full communication answer. It is a thin, general-purpose substrate that keeps ports, multiplexing, and minimal checking, while leaving the rest to the upper layer.
UDP’s core is not “faster”. It only adds the minimum port and checksum semantics on top of IP and leaves connection state, reliability, ordering, and retransmission control to the application or a higher-layer protocol
Why It Appears
IP can move packets best effort, but it does not distinguish between applications, and it does not provide end-to-end process-level delivery. The system still needs a minimal transport semantic layer that at least solves two things:
- How different applications on the same host are distinguished from one another
- Which upper-layer handling logic a datagram should be delivered to after it reaches the host
TCP chooses to add connections, retransmission, in-order delivery, and window control on top of that. UDP keeps only the thinnest layer:
- Ports
- Length
- Checksum
The point is not that every application deserves TCP’s state and latency cost.
The Background It Came From
UDP also came out of the early Internet protocol stack. It faced not “everyone wants a reliable connection”, but another long-standing set of needs:
- Some interactions only want to send one request and receive one response
- Some traffic would rather drop a little than pay more latency for retransmission and queueing
- Some protocols want to define their own reliability policy instead of having TCP decide it all in one package
So UDP is not “a weaker version of TCP”. It is a transport-layer choice with deliberately narrowed responsibility.
Grasp the Main Model First
Reduce UDP to three things:
- Connectionless
- Message-oriented datagrams
- It does not guarantee reliability, ordering, or uniqueness on behalf of the application
The biggest difference from TCP is not just “whether there is retransmission”. The object model is different too:
- TCP gives the application a byte stream
- UDP gives the application datagrams whose message boundaries are still intact
That makes UDP great for “one request, one answer” types of traffic, and it also means the application has to decide what to do if a packet is lost, reordered, or duplicated.
The Most Common Main Path
A typical UDP request-response path can be compressed like this:
The path looks short, but the meaning behind it is important:
- No connection setup is needed first
- No long-lived state is maintained by the protocol layer
- Once the sender has sent it, it does not know whether the peer definitely received it
- If the response never comes back, the application must decide whether to time out and retry
So UDP’s “short path” is not free. It is paid for by pushing complexity upward.
Why UDP Does Not Do Connections or Retransmission
If UDP also took on connection state, retransmission, and in-order delivery, it would become more and more like TCP. But many applications do not want TCP’s unified decision-making.
For example:
- DNS cares more about low-cost short queries than about long connection state
- DHCP initial attachment does not even have a stable network identity yet to maintain a connection
- Real-time audio/video sometimes prefers to lose a frame rather than add retransmission latency
- QUIC wants to define a more modern recovery and multiplexing model on its own
UDP’s value is that it does not decide those things for these protocols ahead of time.
Why “Lightweight” Does Not Mean “Always Faster”
UDP is often understood as “faster than TCP”. That is too rough.
What UDP saves is indeed:
- No connection setup
- Less per-packet state
- Lower protocol overhead
But that does not mean the whole latency and performance picture is always better, because:
- Loss recovery may still have to be added by the application
- Large packets still run into MTU, fragmentation, and middlebox issues
- Applications that send without congestion control may actually behave worse
- In real business traffic, the bottleneck is often not “whether there is a handshake” but network quality and upper-layer policy
So UDP is not “automatically faster”. It just gives you the chance to build something more suitable yourself.
Why DNS and DHCP Prefer UDP
They both fit UDP’s most common path well: short, small, and request-response.
DNS usually has:
- Short query packets
- A clear request/response model
- A situation where it is usually not worth building a connection first just for one lookup
DHCP initial discovery is even more典型:
- The client does not yet have a stable IP
- It needs broadcast discovery to find the server
- The goal is to finish the attachment-phase parameter negotiation as quickly as possible
Both protocols may move to TCP or more complex paths in edge cases, but their default bias toward UDP is not because they do not care about reliability. It is because they want to keep the highest-frequency path cost low first.
Why QUIC Also Uses UDP
QUIC sits on UDP and looks like it is “borrowing a shell”. But that shell gives it exactly the boundary it wants:
- Ports
- Datagram boundaries
- No built-in connection semantics
- No imposed reliability or ordering policy
That lets QUIC reimplement, in user space:
- Handshake
- Retransmission
- Congestion control
- Stream multiplexing
- Connection migration
If it sat directly on TCP, those behavior boundaries would be much harder to change.
Where UDP Fails Most Easily
If it is lost, it is really lost
UDP does not retransmit for you. If the packet does not arrive, the application has to decide on its own whether to add timeout, retry, redundancy, or error correction.
That means “UDP is unreliable” is not an abstract judgment. It is a concrete application-design responsibility.
Large packets and fragmentation become more visible
UDP is often used for short messages, but once the application starts sending large packets, problems show up quickly:
- If the packet exceeds path MTU, fragmentation may happen
- If any fragment is lost, the whole message fails
- Some middleboxes are not friendly to fragmentation
That is why a lot of real-world UDP engineering wisdom is: cut messages small yourself instead of hoping IP fragmentation will save you.
The middle of the network may not treat UDP as kindly as TCP
Many network devices, NATs, ACLs, and carrier policies are more conservative toward UDP. That is why you may see:
- Some port ranges being restricted
- Idle mappings expiring more easily
- Sustained traffic, burst traffic, and large packets being treated differently
So UDP’s problems are not only in the protocol itself. They are also in how real networks support it.
What to Look At in Packet Capture
Do not start by staring at header fields. A better order is below.
First check message boundaries and ports
Confirm:
- Who is sending to whom
- What the source and destination ports are
- How many responses correspond to one request
Because UDP preserves message boundaries, many problems can be judged directly by “did this datagram come back” before you need TCP-style connection-state thinking.
Then check whether there are retries, duplicates, or timeouts
UDP itself does not retransmit, so retries you see in a capture are often application-driven. At that point, separate:
- Whether the application resent after timeout
- Whether duplicate packets appeared in the network
- Whether the server itself responded multiple times
That difference directly changes where you assign responsibility: application, server, or the path itself.
Finally check MTU, fragmentation, and path limits
Many “occasionally broken”, “small packets work, large packets fail” incidents are not application flakiness. They are usually:
- UDP fragments getting dropped
- NAT mappings timing out
- Some link or device being more sensitive to large or bursty UDP packets
If you do not inspect UDP and IP layers first, you can easily wander around the upper protocol for too long.
What Engineering Should Actually Think About UDP Today
- Do not think of UDP as “a naturally faster TCP”. It just gives most decisions back to the upper layer
- Do not treat connectionless as “stateless”. Many applications simply move the state to their own layer
- Do not ignore message boundaries. That is the fundamental application-model difference between UDP and TCP
- Do not treat packet loss, fragmentation, and NAT problems as accidental edge cases. A lot of UDP failures happen exactly at those real-world boundaries
- Do not underestimate the complexity of upper-layer protocols built on UDP just because the header looks simple
Further Reading
- IP - the network layer responsible for reachability and fragmentation boundaries under UDP
- NAT - why many UDP problems show up as mapping timeout and hole-punching issues
- DNS - why classic short queries often run over UDP
- DHCP - why initial attachment depends on UDP broadcast
- QUIC - why the modern Web redoes a transport layer on top of UDP