TCP vs UDP: Differences, Header Sizes and What Uses Which

TCP opens a connection with a three-way handshake and then delivers a reliable, in-order stream of bytes, retransmitting anything lost. UDP sends independent datagrams with no connection, no retransmission and no ordering, in exchange for less overhead: an 8-byte header versus TCP's minimum of 20 bytes.

Choose TCP when every byte must arrive intact and in order (web pages, file transfers, email, SSH). UDP suits traffic where speed matters more than perfect delivery, or where the application handles reliability itself (DNS queries, voice and video, games, and QUIC, the transport under HTTP/3).

Side by side

TCPUDP
Connection setupThree-way handshake before dataNone; the first packet carries data
DeliveryReliable: lost segments are retransmitted"Delivery and duplicate protection are not guaranteed" (RFC 768)
OrderingIn order, as a continuous byte streamEach datagram stands alone; may arrive out of order
Header size20 bytes minimum, up to 60 with options8 bytes, fixed
Flow and congestion controlYes, built inNo; left to the application
Typical usesHTTP/1.1, HTTP/2, SSH, email, file transferDNS queries, QUIC/HTTP/3, voice, video, games

RFC 9293, the current TCP specification, sums up the service in one line: "TCP provides a reliable, in-order, byte-stream service to applications."

The three-way handshake

Before any data moves, TCP endpoints agree on starting sequence numbers so that each side can tell which bytes have arrived. RFC 9293 calls this "the procedure used to establish a connection":

  1. SYN: the client sends a segment with the SYN flag and its initial sequence number.
  2. SYN-ACK: the server replies with its own SYN and initial sequence number, and acknowledges the client's.
  3. ACK: the client acknowledges the server's SYN. The connection is open.

That costs one full round trip before the first request can be sent. On a link with a 100 ms round-trip time, a new TCP connection spends 100 ms just being set up, and a TLS handshake on top adds more. UDP has no equivalent step, which is part of why QUIC (below) was built on it.

Closing a TCP connection has a cost too. The side that closes first waits in the TIME-WAIT state for "2xMSL", with RFC 9293 setting the maximum segment lifetime (MSL) at 2 minutes. That is the TIME-WAIT state you sometimes see in netstat output after a server stops.

How TCP makes delivery reliable

Every byte in a TCP stream has a sequence number. The receiver acknowledges what it has received; anything not acknowledged in time is sent again. Because the receiver knows the sequence, it can also put segments that arrive out of order back in place and discard duplicates before handing the data to the application.

That guarantee has a side effect called head-of-line blocking: if one segment is lost, everything behind it waits until the retransmission arrives, even if later data is already sitting in the receiver's buffer. RFC 9114 describes exactly this problem for HTTP/2, which multiplexes many requests over one TCP connection: "a lost or reordered packet causes all active transactions to experience a stall."

Header sizes, field by field

UDP's header, defined in RFC 768, has four 16-bit fields:

 0      7 8     15 16    23 24    31
+--------+--------+--------+--------+
|   Source Port   |  Destination    |
|                 |      Port       |
+--------+--------+--------+--------+
|     Length      |    Checksum     |
+--------+--------+--------+--------+

4 × 16 bits = 64 bits = 8 bytes. The Length field counts header plus data, and RFC 768 states "the minimum value of the length is eight," which is an empty datagram.

TCP's header has a Data Offset field that gives the header length in 32-bit words. Options exist only when it exceeds 5, so the minimum header is 5 × 4 = 20 bytes; RFC 9293 notes the header "is 20 in the (rare) case that no options are present." Data Offset is 4 bits wide, so its maximum value of 15 allows a header of 15 × 4 = 60 bytes. The extra fields hold the sequence and acknowledgment numbers, flags such as SYN and ACK, and the receive window used for flow control.

For a 1,000-byte payload, the difference is 12 bytes or more per packet. It matters most for small, frequent messages, where headers make up a larger share of each packet.

What uses which

HTTP/1.1 and HTTP/2: TCP

RFC 9114 notes that "HTTP/2 has been used primarily with TLS over TCP." HTTP/1.1 has been used over several transports, but on the web it runs over TCP, usually with TLS for HTTPS.

HTTP/3: QUIC over UDP

HTTP/3 keeps the same request and response semantics but moves them to a new transport. RFC 9114: "HTTP/3 supports the same semantics over a new transport protocol: QUIC." And RFC 9000: "QUIC packets are carried in UDP datagrams to better facilitate deployment in existing systems and networks."

QUIC rebuilds reliability and ordering on top of UDP, but per stream instead of per connection, so a lost packet on one stream "does not prevent progress on other streams." Its handshake "combines negotiation of cryptographic and transport parameters", folding the TLS handshake into connection setup instead of running it after a TCP handshake. RFC 9114 also notes that "blocking UDP" can prevent a QUIC connection, which is why clients keep TCP as a fallback.

DNS: UDP first, TCP when needed

A DNS query and answer usually fit in a single small packet, so a handshake would double the lookup time for no benefit. RFC 1035 assigns port 53 for DNS over both UDP and TCP and limits classic UDP messages to 512 bytes; a longer response is truncated with the TC flag set, and the client retries over TCP. RFC 7766 made TCP mandatory: "All general-purpose DNS implementations MUST support both UDP and TCP transport," and TCP "is always used for full zone transfers." See how DNS works for the full lookup.

Live audio, video and games: usually UDP

For live media, data that arrives late is useless. Waiting for a retransmission (TCP's behaviour) produces a freeze; skipping the lost packet (possible over UDP) produces a brief glitch. Applications choose the glitch.

Seeing it on your own machine

On Windows, netstat -ano -p TCP lists TCP connections with their state (LISTENING, ESTABLISHED, TIME_WAIT), while netstat -ano -p UDP lists UDP endpoints, whose State column is empty because there is no connection to be in a state:

  Proto  Local Address          Foreign Address        State           PID
  UDP    0.0.0.0:123            *:*                                    71064
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       65732

(Real lines from both commands on the machine this article was checked on.) On Linux, ss -tan and ss -uan show the same split. If a port you need is already taken, the "port already in use" guide shows how to find the process.

Frequently asked questions

Is UDP faster than TCP?
UDP has less overhead: no handshake before the first byte, a smaller header (8 bytes versus at least 20), and no waiting to retransmit lost packets. That makes it lower-latency, not necessarily higher-throughput. If the application needs every byte in order, it has to rebuild those guarantees on top of UDP, as QUIC does.
Why do games and video calls use UDP?
For live data, a late packet is worthless. TCP would hold back newer data until a lost packet is retransmitted, which shows up as a freeze. Over UDP the application can skip the lost packet and use the next one, accepting a brief glitch instead of a stall.
Can a port be used by TCP and UDP at the same time?
Yes. TCP and UDP have separate port spaces, so TCP port 53 and UDP port 53 are different endpoints. DNS uses both: RFC 1035 assigns port 53 for DNS over UDP and over TCP.
Does HTTPS use TCP or UDP?
Both, depending on the version. HTTP/1.1 and HTTP/2 run over TLS on TCP. HTTP/3 runs over QUIC, which is carried in UDP datagrams. RFC 9114 notes that blocked UDP can prevent a QUIC connection, so clients that support HTTP/3 keep HTTP/2 or HTTP/1.1 over TCP available as well.

Sources