TCP vs UDP
A live TCP vs UDP speed test, and an explanation of what you just watched happen.
1. The live comparison
Run the live demo — click a button below
TCP
Reliable, ordered, retransmits lost data.
UDP
Fast, unordered, nothing is retransmitted.
Click a button. Both fetch the exact same file from the exact same server — … of random data. One travels over a plain TCP connection. The other travels over WebTransport, a QUIC/UDP-based transport that behaves like real UDP: packets can arrive out of order, and any packet that gets lost simply stays lost — nothing here retries or resends on your behalf. That's UDP packet loss in its rawest form, and nothing here is artificially slowed down or dropped for effect.
On a slow or unreliable connection, try a smaller file first — with fewer packets in flight there's a real chance the UDP transfer completes with nothing lost at all. A larger file gives loss more opportunity to show up.
On a short, clean connection — like the one between your browser and this demo server — you should expect both transfers to finish quickly and completely, often with the UDP transfer finishing measurably faster. That is not a coincidence, and it is not the whole story either. Read on below for what you just watched happen.
Abstract. Section 1 above runs the same file download twice — once over TCP, once over UDP — against a real server, over your real network connection, with no simulated slowdown and no simulated packet loss. Sections 2 through 10 below explain why the two results look the way they do: what each protocol actually does to your data, why one is reliable and the other is not, and why both still matter today.
2. What is TCP?
TCP — the Transmission Control Protocol, defined in RFC 9293 — is connection-oriented. Before a single byte of your data moves, the two sides perform a three-step handshake to agree that a connection exists:
Diagram: the client sends a SYN packet to the server; the server replies with SYN-ACK; the client sends ACK; the connection is now established.
That handshake costs one full round trip before any of your data even starts moving — the client's first packet has to reach the server and the server's reply has to come back before the client can send anything else. On a connection with 50 ms of latency, that is 50 ms spent before the download even begins.
Once the connection is open, TCP guarantees three things your application never has to think about:
- Reliability. Every byte is numbered. If the receiver notices a gap, the sender resends the missing data. Nothing is silently dropped.
- Ordering. Bytes are handed to your application in the exact order they were sent, even if the underlying packets arrived out of order.
- Congestion control. TCP starts sending cautiously and gradually speeds up (“slow start”), backing off automatically if it detects packet loss, so it shares the network reasonably with everyone else on it.
All of that bookkeeping has to travel somewhere, and it travels in the header attached to every single TCP segment — 20 bytes at minimum, before your data even starts:
Fields, in order: Source Port, Destination Port, Sequence Number, Acknowledgment Number, Data Offset, reserved bits, control flags (URG, ACK, PSH, RST, SYN, FIN), Window, Checksum, and Urgent Pointer.
Figure 2. The TCP header — 20 bytes of bookkeeping per segment.
3. What is UDP?
UDP — the User Datagram Protocol, defined in a single three-page document, RFC 768 — is connectionless. There is no handshake. The sender addresses a packet (called a datagram) to a destination and puts it on the wire. That is the entire protocol.
UDP makes none of TCP's promises:
- No delivery guarantee. A lost datagram is simply gone.
- No ordering guarantee. Datagrams can arrive in any order, or not at all.
- No congestion control. UDP will send as fast as the application asks it to, without slowing down for a congested network — unless the application built that logic itself.
In exchange, the header shrinks to almost nothing — 8 bytes, a quarter the size of TCP's minimum:
Fields, in order: Source Port, Destination Port, Length, and Checksum.
Figure 3. The entire UDP header — 8 bytes, full stop.
Note what is not in that header: no sequence number, no acknowledgment number, no window size. UDP's checksum can tell a receiver that a datagram arrived corrupted — but there is no mechanism to ask for it again. It is simply discarded.
4. Side-by-side comparison
| Property | TCP | UDP |
|---|---|---|
| Connection | Connection-oriented (handshake required) | Connectionless |
| Reliability | Guaranteed — lost data is retransmitted | None — lost data stays lost |
| Ordering | Guaranteed in-order delivery | Not guaranteed |
| Congestion control | Built in (slow start, backoff) | None by default |
| Header size | 20 bytes minimum | 8 bytes |
| Setup latency | One round trip before data flows | None — first packet can carry data |
| Typical use | Web pages, email, file transfer, SSH | Video calls, live streaming, games, DNS |
5. Why TCP is slower, by design
Three separate costs stack up, all in service of reliability:
- Handshake latency. One round trip is spent before any application data moves at all.
- Acknowledgment overhead. The sender has to track which bytes have been confirmed and hold unacknowledged data in memory in case it needs to resend it.
- Slow start. TCP deliberately sends conservatively at first and ramps up, so it doesn't flood a network it doesn't understand yet. On a short download, the transfer can finish before TCP ever reaches full speed.
None of this is a flaw — it's the entire point of the protocol. A web page, an email, or a downloaded file with a missing chunk in the middle isn't a faster version of that page, email, or file. It's a broken one. TCP trades speed for a guarantee that what arrives is exactly what was sent.
6. Why UDP is faster, and what you give up
UDP is faster for the mirror-image reason: it skips all three of those costs. No handshake, no acknowledgment bookkeeping, no deliberate ramp-up. The first packet sent is already carrying data, and every subsequent packet is independent of the ones before it.
What you give up is everything TCP was providing. If a UDP packet is lost, nothing notices at the protocol level — no error is raised, no retransmission happens. The application either doesn't need that data (one stale video frame among sixty per second), or it has to build its own recovery on top, which is exactly what protocols like QUIC (Section 8) do.
7. Which protocol powers what
| Application | Protocol | Why |
|---|---|---|
| Web pages (HTTP/1.1, HTTP/2) | TCP | A page missing bytes is a broken page, not a faster one |
| Web pages (HTTP/3) | UDP, via QUIC | Same reliability guarantee, rebuilt over UDP to cut handshake latency — see Section 8 |
| Email (SMTP, IMAP) | TCP | A message must arrive complete |
| File transfer, SSH, SCP | TCP | A file with missing bytes is useless |
| DNS lookups | UDP (TCP for large replies) | One small request/response — cheaper to retry at the application level than to pay handshake cost on every lookup |
| Voice and video calls | UDP | A late packet is worse than a lost one |
| Live streaming | Usually UDP | Freshness matters more than completeness |
| Online multiplayer games | UDP | A resent position update arrives after it's already stale |
| VPN tunnels (WireGuard) | UDP | Avoids "TCP over TCP," which causes its own performance problems when tunneling TCP traffic |
8. How this demo actually works
Browsers have no way to open a raw UDP socket — that's a deliberate sandbox restriction, not a missing feature, and it applies equally whether the code asking is JavaScript or WebAssembly. The closest thing available from a browser tab, and what powers the UDP side of this WebTransport demo, is WebTransport, which runs over QUIC — itself built on UDP — and exposes an unreliable, unordered "datagrams" channel. Think of it as UDP with encryption and congestion control attached, but the same core property: nothing sent over it is acknowledged or resent.
The server chunks the file into small datagrams and sends each one exactly once, in order, with no retries. Your browser reassembles whatever arrives. If a datagram never shows up, the demo reports it as lost — it does not fake completion, and it does not artificially drop packets to manufacture a more dramatic result. On a clean connection, genuinely nothing is lost, and that's shown honestly too.
Every completed transfer is also verified: the browser computes a SHA-256 hash of what it received and compares it against the server's hash of the original file. That's the "Integrity" result you see next to each download — not a guess, a cryptographic check that the bytes match exactly.
9. Frequently asked questions
Is UDP always faster than TCP?
Not always, and not by much on a short, clean connection — most of TCP's overhead is the one-time handshake, not a per-byte cost. UDP's advantage grows on high-latency or lossy links, where TCP's handshake and retransmissions cost more round trips.
Can UDP be made reliable?
Yes, but the application has to build it. That's what QUIC does: it re-implements acknowledgment, retransmission, and ordering on top of UDP for the streams that need it, while still allowing raw, unreliable datagrams for the parts that don't.
Why did my UDP result show 0% loss?
Because nothing was lost. Real packet loss on a short hop between your browser and a well-connected server is rare. It becomes far more visible over long-haul, congested, or wireless links — exactly the conditions where TCP's retransmission logic starts costing real time.
Is the download in this demo real?
Yes. Real bytes travel over a real connection, which is how the byte counts, throughput, and integrity hash above are computed — none of it is simulated. The demo also lets you save the completed file to disk once a transfer finishes with verified integrity.
What's actually in a "packet" versus a "datagram"?
They're often used loosely to mean the same thing. This page uses "packet" generically and "datagram" specifically for UDP's connectionless, self-contained unit — a term UDP's own RFC uses in its name.
10. References
- RFC 9293 — Transmission Control Protocol (TCP), rfc-editor.org/rfc/rfc9293
- RFC 768 — User Datagram Protocol, rfc-editor.org/rfc/rfc768
- RFC 9000 — QUIC: A UDP-Based Multiplexed and Secure Transport, rfc-editor.org/rfc/rfc9000
- RFC 9114 — HTTP/3, rfc-editor.org/rfc/rfc9114
- W3C WebTransport, developer.mozilla.org/docs/Web/API/WebTransport_API