What problem do they solve?
- TCP and UDP live at Layer 4 (transport). They move bytes between endpoints, but with different guarantees and costs.
TCP: reliable streams
- Connection‑oriented, ordered, reliable byte stream.
- Built‑in congestion control (Reno/Cubic/BBR), flow control (window), backpressure.
- Handshakes (3‑way + TLS) and retransmissions add latency, but simplify application logic.
When TCP shines
- Web/API traffic, file transfer, database connections, anything that needs integrity and order.
UDP: simple datagrams
- Connectionless, best‑effort delivery, no ordering by default.
- Minimal overhead → lower latency and jitter when loss is tolerated.
When UDP shines
- Real‑time voice/video, gaming state updates, telemetry where freshness beats perfection.
QUIC (HTTP/3) on UDP
- TLS 1.3 built in, connection migration, stream multiplexing without head‑of‑line blocking.
- 0‑RTT for faster handshakes; improves performance over lossy/variable networks.
Head‑of‑line blocking (HOLB)
- TCP streams suffer HOLB: one lost packet stalls subsequent data.
- QUIC avoids cross‑stream HOLB by independent streams over UDP.
NATs and middleboxes
- UDP may be blocked/throttled in some networks; keep‑alives needed to maintain NAT bindings.
- TCP is more universally allowed but can be proxied/terminated unexpectedly.
Code: TCP echo server (Node.js)
// language-javascript
import net from 'node:net'
const server = net.createServer((socket) => {
socket.on('data', (chunk) => socket.write(chunk))
})
server.listen(9000)
Code: UDP ping (Node.js)
// language-javascript
import dgram from 'node:dgram'
const socket = dgram.createSocket('udp4')
socket.send(Buffer.from('ping'), 41234, '127.0.0.1')
socket.on('message', (msg) => console.log('got', msg.toString()))
Code: QUIC‑like behavior with HTTP/3 (nginx)
# language-nginx
server {
listen 443 quic reuseport;
listen 443 ssl;
ssl_protocols TLSv1.3;
add_header alt-svc 'h3=\":443\"; ma=86400';
}
Congestion control overview
- Reno/Cubic: loss‑based; increase window until loss, then cut.
- BBR: estimates bottleneck bandwidth and RTT; often better on modern networks.
Reliability patterns over UDP
- Add sequence numbers, ACKs/NACKs, and retransmission timers if you need reliability.
- Use FEC (forward error correction) for live video.
Analogy
- TCP is a carefully managed conveyor belt: parts arrive in order, foreman slows the belt if downstream is busy.
- UDP is a fleet of couriers: some packages may be late or lost, but most arrive fast; you decide what to resend.
FAQ
- Can I build reliable messages over UDP? Yes—many protocols do. But expect to re‑implement pieces of TCP.
- When is UDP worse? Enterprise networks that drop UDP; or when you actually need ordering/reliability.
Try it
Measure p95 latency and loss under simulated network conditions (tc netem) for both a TCP and UDP flow to validate your choice.