The Core Difference
TCP guarantees that every byte you send arrives, in order, exactly once. If a packet is lost, TCP retransmits it. If packets arrive out of order, TCP reorders them. This is "reliable, ordered delivery."
UDP sends packets and forgets about them. No retransmission, no ordering, no acknowledgement. If a packet is lost, it's gone. If packets arrive out of order, the application sees them out of order.
Why would you ever want UDP? Because TCP's guarantees cost time. Sometimes "best effort, fast" beats "perfect, slow."
TCP in Detail
TCP works hard to be reliable:
Three-way handshake. Before sending data, client and server exchange SYN, SYN-ACK, ACK packets to establish a connection.
Sequence numbers. Every byte is numbered. Receiver acknowledges what it got.
Retransmission. If sender doesn't get an ACK, it resends.
Flow control. Sliding window prevents sender from overwhelming receiver.
Congestion control. Slow down if the network is overloaded; speed up if not. Algorithms: Reno, Cubic, BBR.
Ordered delivery. Receiver buffers out-of-order packets until missing ones arrive.
All this overhead means TCP isn't fast. It's reliable. Different goal.
UDP in Detail
UDP is almost nothing. Packet header has source port, destination port, length, checksum. Send it and pray.
What you get:
Lower latency (no handshake, no waiting for ACKs).
Lower overhead (smaller packets).
No connection state to maintain.
Multicast/broadcast support (TCP can't do these).
What you don't get:
Any guarantee that data arrives.
Any guarantee about order.
Any built-in flow control or congestion control.
Where TCP Wins
HTTP / HTTPS: web pages need every byte. Until QUIC, all HTTP was TCP.
Email (SMTP, IMAP, POP3): can't lose chunks of an email.
File transfer (FTP, SCP): need every byte.
Database connections: can't drop a query mid-execution.
SSH: reliability matters; latency matters less.
Where UDP Wins
DNS: queries are small, retries are cheap, latency matters. UDP is the default; TCP fallback for big responses.
Video calls (Zoom, Google Meet): if a packet of audio is lost, retransmitting it 200ms later is useless. Just skip it. Real-time matters more than completeness.
Online gaming: same logic. A position update from 500ms ago is irrelevant.
Live streaming (parts of): some streaming protocols use UDP for low latency.
VoIP (RTP): voice packets can drop without ruining the call.
VPNs (some): WireGuard uses UDP for speed.
The Hybrid Reality: QUIC
QUIC takes UDP and adds the parts of TCP it wants (reliability, ordering, congestion control) in user space, while leaving out what it doesn't (head-of-line blocking on the connection level).
Why? Because TCP can't be changed without OS updates. QUIC ships in the application, evolves rapidly, and gets the best of both.
HTTP/3 runs on QUIC. So do increasing numbers of other protocols. The "TCP for reliable, UDP for fast" simple answer is breaking down.
NAT and Firewalls
One real-world consideration: TCP connections are easier for NAT and firewalls to track. UDP has no connection concept; firewalls handle it less gracefully.
For NAT traversal in P2P apps (WebRTC), UDP requires "hole punching" tricks. TCP usually just works.
How Applications Choose
Default: TCP. It's what most things use. Use UDP when:
Latency is critical.
Lost packets are tolerable (because newer data makes old data obsolete).
You're building real-time, multimedia, or specific types of distributed systems.
You need multicast.
If you reach for UDP, you're committing to handling any reliability/ordering you need yourself. That's a lot of work. Consider QUIC instead, which gives you a sane middle ground.
Comparison
| TCP | UDP | |
|---|---|---|
| Reliability | Guaranteed | None |
| Ordering | Guaranteed | None |
| Connection | Yes (handshake) | No |
| Speed | Slower | Faster |
| Overhead | Higher (~20+ byte header) | Lower (8 byte header) |
| Flow / Congestion | Built-in | None |
| Use Cases | Web, email, files | DNS, video, gaming, VoIP |
The One Thing to Remember
TCP guarantees delivery at the cost of latency. UDP gives you raw speed at the cost of reliability. The right choice depends on whether your application would rather wait for missing data or skip it. Most things use TCP because most things would. Specialized real-time systems use UDP. And QUIC is increasingly the answer for systems that want both.