UDP: The Full Breakdown
1. THE GIST
UDP (User Datagram Protocol) is the "fire and forget" layer 4 protocol that sits on top of IP. Unlike TCP, it's stateless, connectionless, and has zero handshake overhead — you just blast a datagram at a destination and move on. It's the first protocol that introduces ports, which means for the first time you can address specific processes on a host, not just the host itself. The header is a laughably small 8 bytes. No acknowledgements, no ordering guarantees, no congestion control — but that's the point. If your app needs speed over correctness (video streaming, DNS, gaming, WebRTC, VPNs), UDP is your tool. The tradeoff is that you own whatever reliability you need — you build it yourself at the application layer, or you don't and you're okay with that.
2. THE BREAKDOWN
What UDP Actually Is
- Layer 4 protocol — sits directly on top of IP (Layer 3)
- Message-based, not stream-based (unlike TCP's "hose of bytes")
- Each datagram is a self-contained unit — it either arrives whole or not at all
- Stateless: neither sender nor receiver stores any connection state
The Port Concept (Why It Matters)
Before UDP, IP could only address a host. UDP introduced ports — 16-bit numbers (0–65535) that identify a specific process on that host. This is the foundation of all multiplexing in networking.
The 4-tuple that uniquely identifies any communication:
Source IP | Source Port | Destination IP | Destination Port
Fix 3 of these 4 values and you can have at most ~65,000 concurrent senders from one host.
The UDP Header (8 bytes total)
| Field | Size | Purpose |
|---|---|---|
| Source Port | 2 bytes | Identifies sending process |
| Destination Port | 2 bytes | Identifies receiving process |
| Length | 2 bytes | Size of datagram (header + data) |
| Checksum | 2 bytes | Basic integrity check |
That's it. No sequence numbers. No ACKs. No window sizes.
Multiplexing vs Demultiplexing
- Multiplexing: Multiple apps on one host share one IP address — their packets are funneled into one wire
- Demultiplexing: On the receiving end, the OS reads the destination port and routes the datagram to the correct process
Use Cases Where UDP Wins
- Video streaming — dropped frames are acceptable; stalling is not
- DNS — short request/response; no need for a full connection setup
- VPNs (e.g., OpenVPN, WireGuard) — avoids TCP-in-TCP meltdown
- WebRTC — browser peer-to-peer; raw UDP isn't exposed in browsers, WebRTC wraps it
- Online gaming — latency matters more than packet loss
Security Implications
- UDP flooding / DoS: No handshake means anyone can send datagrams to any server and it has to process them — that costs CPU/memory
- DNS amplification attack: Attacker spoofs the victim's IP as source, sends small DNS queries to open resolvers, which reply with large responses — all hitting the victim
- IP spoofing is possible because there's no handshake to validate the sender
3. ENGINEER'S NOTEBOOK
Core idea? Send a message, don't wait for a receipt. Speed and simplicity over reliability.
Key moving parts?
- Socket created with
SOCK_DGRAM(notSOCK_STREAM) - Bind to an address + port to start listening
recvfrom()/sendto()instead ofread()/write()- Each call to
recvfromgets exactly one datagram — there's no stream to parse
Gotchas and edge cases:
- Port exhaustion is real — if your app spins up 65k+ parallel processes all sending to the same destination:port combo, you're dead
- Checksum won't save you from all corruption — it's a basic integrity check, not cryptographic
- Listening on
0.0.0.0vs127.0.0.1— huge security difference. Binding to all interfaces accidentally exposes internal services - No loop = one-shot server — a C UDP server with no loop receives one datagram and exits. Always loop
recvfrom() - Buffer size matters — if your buffer is 1024 bytes and the datagram is larger, you truncate silently
Key terms:
- Datagram: A self-contained, independently routed UDP message
- Stateless: No memory of past interactions — every datagram is treated fresh
- Port: A 16-bit number identifying a process on a host
- Multiplexing: Many processes sharing one network interface via ports
- Checksum: CRC-style integrity check over the header + data
- TCP Meltdown: What happens when you tunnel TCP inside TCP — retransmission storms
Don't forget this:
UDP doesn't lose your packets — the network does. UDP just doesn't tell you about it or retry. That distinction matters when you're debugging.
4. QUICK REFERENCE CARD
UDP at a glance
─────────────────────────────────────────
Layer: 4 (Transport)
Type: Connectionless, Stateless
Header size: 8 bytes
Ports: 0–65535 (16-bit)
Delivery: Not guaranteed
Order: Not guaranteed
Handshake: None
ACKs: None
4-tuple identity:
src_ip | src_port | dst_ip | dst_port
Common ports:
53 → DNS
67 → DHCP
5500 → custom app (example)
Wins at: Speed, simplicity, scale
Loses at: Reliability, ordering, security
Rule of thumb:
If you can tolerate loss → UDP
If you can't → TCP
If you need both → build reliability at app layer
5. THE "AHA" MOMENT
The Tricky Bit: Why does UDP get used for VPNs instead of TCP? Isn't reliability good?
The Analogy — TCP in TCP is like tracking a tracked package:
Imagine you hire a courier (TCP) who obsessively tracks every package and will re-deliver if anything goes wrong. Now you put that courier inside another courier service (the VPN tunnel, also TCP) that does the same thing.
Now when a package gets lost, both couriers start independently re-delivering at the same time. They don't know about each other. The outer courier is like "resending!" and the inner one is also screaming "resending!" — and they're stepping on each other's feet, creating a storm of redundant re-delivery attempts that grinds the whole operation to a halt.
That's TCP Meltdown.
UDP as the VPN tunnel is like using a plain van with no tracking. The inner courier (your app's TCP) still tracks packages obsessively — that's fine. But the van just drives. No double-tracking, no meltdown. The reliability you need is handled exactly once, at exactly the right layer.
6. SHOW ME THE CODE
import dgram from 'dgram';
// Create a UDP socket - 'udp4' means IPv4
// This is equivalent to socket(AF_INET, SOCK_DGRAM, 0) in C
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
// msg is a Buffer — raw bytes, not a string
// rinfo contains: address, port, family, size of the sender
console.log(`Got datagram from ${rinfo.address}:${rinfo.port}`);
console.log(`Message: ${msg.toString()}`);
console.log(`Size: ${rinfo.size} bytes`);
// UDP is connectionless — to reply, you must explicitly
// send back to the sender's address + port from rinfo.
// Unlike TCP, there's no persistent "connection" to write to.
const reply = Buffer.from('ACK'); // our own manual acknowledgement
server.send(reply, rinfo.port, rinfo.address, (err) => {
if (err) console.error('Send failed:', err);
});
});
server.on('error', (err) => {
console.error('Server error:', err);
server.close();
});
server.on('listening', () => {
const addr = server.address();
// Bind explicitly to 127.0.0.1, NOT 0.0.0.0
// 0.0.0.0 would expose this to all interfaces — a security risk
console.log(`Listening on ${addr.address}:${addr.port}`);
});
// Bind to loopback only — deliberate, not lazy
server.bind(5500, '127.0.0.1');
Test it with netcat:
echo -n "hello" | nc -u 127.0.0.1 5500
7. IN THE WILD
DNS — Every time you type a URL, your OS sends a UDP datagram to port 53. The response fits in one packet. A full TCP handshake for something this small would be absurd overhead. DNS does fall back to TCP for large responses (DNSSEC, zone transfers), but the default is UDP.
Game servers — Games like CS:GO, Valorant, and Rocket League send player position updates many times per second. A dropped position update is irrelevant — the next one arrives in 16ms anyway. TCP's retransmission would make the game feel laggy. Instead, game engines build their own lightweight reliability on top of UDP — sequence numbers for inputs, interpolation for missing frames.
WebRTC (Google Meet, Discord video) — Browsers don't expose raw UDP sockets for security reasons. WebRTC wraps UDP with just enough structure (SRTP for encryption, RTCP for stats) to make it usable for media. It also handles NAT traversal (STUN/TURN) which TCP can't do cleanly.
WireGuard VPN — Uses UDP exclusively. Each packet is independently encrypted. No TCP meltdown, minimal state on the server side, and it's absurdly fast because of it. WireGuard's server-side state per peer is kilobytes; OpenVPN's TCP mode can be orders of magnitude heavier.
Observability / Metrics (StatsD) — Many internal metrics pipelines use UDP. If a metrics packet drops, nobody cares — you lose one data point out of millions. The cost of guaranteed delivery for every counter increment would be wildly disproportionate.
The scaling angle: Because UDP is stateless, a UDP server can handle far more concurrent "connections" than a TCP server with equivalent hardware. There's no per-connection buffer, no state machine, no handshake overhead. This is why DNS resolvers can handle millions of QPS on modest hardware.
8. EXPLAIN IT TO A NON-TECH FRIEND
Imagine you're sending postcards vs. sending registered mail.
Registered mail (TCP): You fill out forms, the post office tracks every step, you get a signature confirmation, and if anything goes wrong they resend it. It's reliable but slow and involves a lot of paperwork.
Postcards (UDP): You write a message, drop it in the mailbox, and walk away. No tracking number, no signature, no guarantee it arrives. But it's instant and dirt cheap — and most of the time it gets there just fine.
Now imagine you're a TV news channel broadcasting live. You're sending thousands of postcards per second — one for each frame of video. If one postcard gets lost, you don't want the post office to stop everything, track down that lost card, and resend it — by the time it arrived, the moment has passed and everything would be out of sync. You'd rather just skip that one frame and keep the broadcast flowing.
That's UDP. It's postcards. Fast, simple, no waiting around. When you're streaming video, playing online games, or making a video call, postcards are exactly what you want.