Skip to main content
Explainer · networking

TCP vs UDP: what's the difference?

Almost every connection your computer makes rides on one of two transport protocols. TCP trades a little speed for guaranteed, ordered delivery; UDP throws packets into the network and hopes for the best. Here is how they differ, why the tradeoff exists, and how modern protocols like QUIC get the best of both.

Both live one layer above IP

The Internet Protocol (IP) moves packets between addresses, but it makes no promises: packets can be lost, duplicated, delayed, or arrive out of order, and IP has no concept of an application waiting for them. That is deliberate — IP keeps the network simple and pushes complexity to the edges. Sitting directly on top of IP are the two transport protocols that fill in the missing pieces: TCP (Transmission Control Protocol) and UDP (User Datagram Protocol).

Both take the raw, unreliable packet delivery that IP offers and add the one feature every application needs: ports, so that a single machine can run many network services at once and the operating system knows which program each packet belongs to. That is where their similarity ends. TCP layers a full reliability system on top; UDP adds almost nothing beyond ports and a checksum. Everything else about the two protocols follows from that single design choice.

TCP: connection-oriented and reliable

TCP is built around the idea of a connection — a stateful, two-way conversation that both ends agree to open, maintain, and close. Once the connection is established, TCP presents the application with something IP never provides: a reliable, ordered stream of bytes. Whatever you put in one end comes out the other end in the same order, complete, with nothing missing and nothing duplicated.

To deliver that guarantee, TCP does a lot of bookkeeping:

The 3-way handshake

Before any application data flows, a TCP connection is opened with a three-step exchange, the famous 3-way handshake:

  1. The client sends a SYN (“synchronize”) packet with its starting sequence number.
  2. The server replies with a SYN-ACK, acknowledging the client's SYN and sending its own starting sequence number.
  3. The client sends a final ACK, acknowledging the server's SYN. The connection is now established and data can flow both ways.

That handshake costs a full round trip before the first byte of useful data moves, and closing a connection cleanly takes another exchange. It is a modest price for a web page or a file download, but it is pure overhead you would rather avoid when every millisecond counts.

UDP: connectionless and fire-and-forget

UDP takes the opposite stance. There is no connection, no handshake, and no state to maintain — you simply address a datagram to an IP and port and send it. The UDP header is tiny (just source port, destination port, length, and checksum), so there is almost no per-packet overhead. UDP does not number packets, does not acknowledge them, does not retransmit lost ones, and does not reorder anything. If a datagram is lost or arrives out of order, the application either copes with it or does not — UDP will never tell you.

This sounds worse, and for bulk data it usually is. But “fire and forget” is exactly what some applications want. There is no setup delay, no waiting for acknowledgements, and no head-of-line blocking (more on that below). For anything where a late packet is useless anyway, the reliability machinery of TCP is dead weight — and UDP's minimalism becomes a feature, not a bug. Any reliability an application does need, it can build itself, on its own terms, on top of UDP.

The tradeoff in one sentence

TCP buys you reliability and ordering at the cost of latency and overhead; UDP buys you low latency and low overhead at the cost of reliability and ordering. Neither is “better” — they are tuned for different failure modes. If a missing byte would corrupt the result, you want TCP. If a delayed byte is worse than a missing one, you want UDP.

Which protocol does each application use?

Typically TCP

Typically UDP

Head-of-line blocking, and why it matters

TCP's in-order guarantee has a subtle cost called head-of-line blocking. Because TCP hands bytes to the application strictly in order, a single lost packet stalls everything behind it — even data that has already arrived safely must sit in a buffer, undelivered, until the missing packet is retransmitted and fills the gap. For a file download that is invisible; the transfer just pauses for a moment. For a real-time stream it is disastrous, because the delayed data is often already obsolete by the time it is released.

UDP has no head-of-line blocking, because it makes no ordering promise in the first place — each datagram is delivered (or lost) on its own. That is precisely why real-time applications reach for UDP: they would rather handle a gap themselves than let one lost packet freeze the whole flow.

How QUIC and HTTP/3 get the best of both

For decades the choice was binary: TCP's reliability with its head-of-line blocking and handshake latency, or UDP's speed with no guarantees at all. QUIC changes that. QUIC is a modern transport protocol that runs on top of UDP and rebuilds the reliability, ordering, and congestion control that TCP provides — in software, at the application layer — while keeping UDP's freedom from connection state in the kernel.

Because it starts from a clean slate, QUIC fixes several long-standing TCP pain points:

HTTP/3 is simply HTTP running over QUIC, and it is now widely deployed across the web. QUIC does not delete TCP from the internet — enormous amounts of traffic still use it, and QUIC clients typically fall back to TCP when UDP is blocked — but it shows that the old TCP-versus-UDP tradeoff was never a law of nature. UDP was simply a flexible enough foundation to build something better on.

Ports apply to both

One point that trips people up: a port number is not tied to a single protocol. Port 443, for example, is used by HTTPS over TCP and by HTTP/3 (QUIC) over UDP. The operating system tracks TCP and UDP ports separately, so a service can listen on “the same” port number on both protocols without conflict. When you check whether a port is reachable, you are always testing a specific protocol. You can see this in practice with the port checker, and the common ports reference lists which services use TCP, UDP, or both. If you want to see the path packets actually take to a host, the traceroute tool walks it hop by hop.

Frequently asked questions

Is TCP or UDP faster?

UDP has lower latency and less overhead because it skips connection setup, acknowledgements, and retransmissions — it sends packets immediately with no handshake and never waits for a lost one. That makes it the better choice for real-time traffic, where a late packet is worse than a missing one. But for bulk transfers TCP usually achieves higher sustained throughput, because its congestion control adapts the sending rate to what the network can actually carry. “Faster” depends on what you are measuring.

Why does DNS use UDP instead of TCP?

A typical DNS query and its answer each fit in a single small packet, so setting up a TCP connection first would cost more round trips than the lookup itself. UDP lets the resolver fire off a query and get an answer in one round trip. DNS still falls back to TCP when a response is too large for one UDP packet — large DNSSEC-signed answers or zone transfers, for example — so both protocols play a role.

Does QUIC replace TCP?

QUIC runs on top of UDP and reimplements the reliability, ordering, and congestion control that TCP provides, plus built-in encryption and independent streams that avoid head-of-line blocking; HTTP/3 runs over QUIC. It does not delete TCP from the internet — countless services still use TCP, and QUIC connections often fall back to TCP when UDP is blocked — but for web traffic QUIC is increasingly the default, giving applications UDP's flexibility with TCP-grade reliability.

Related reading