TCP vs UDP: What They Are and How They Differ

TCP and UDP explained: how the internet's two transport protocols differ in reliability, speed, and overhead, and when each one is the right choice.

TCP vs UDP: What They Are and How They Differ

TCP and UDP are the two transport layer protocols that carry nearly all traffic on the internet. TCP, the Transmission Control Protocol, delivers data reliably and in order. UDP, the User Datagram Protocol, sends data fast and light with no guarantee that anything arrives. Almost every application builds on one of these two, and the choice between them shapes how that application behaves when the network gets rough.

What Is TCP?

TCP is a connection-oriented protocol. Its current IETF specification updates the original 1981 standard while preserving the same core model. Before any data moves, both endpoints complete a three-way handshake to establish a connection. From then on, TCP treats everything the application sends as one continuous stream of bytes.

Reliability is TCP's core job. Every byte gets a sequence number, and the receiver acknowledges what it has received. Lost segments get retransmitted. Flow control keeps a fast sender from overwhelming a slow receiver, and congestion control algorithms such as CUBIC or BBR keep the shared network from collapsing under load.

None of this is free. A TCP header runs at least 20 bytes, both endpoints hold connection state, and retransmission adds latency whenever packets drop.

What Is UDP?

UDP strips all of that away. It's connectionless: a sender fires a self-contained datagram at a destination IP and port and moves on. No handshake, no sequence numbers, no acknowledgments, no retransmission. If a datagram is lost in transit, UDP never knows and never cares.

The header is just 8 bytes: source port, destination port, length, and checksum. Message boundaries survive because each datagram is a discrete unit, so what the application sends is what arrives, if it arrives. Delivery is best effort, and as Cloudflare's UDP overview notes, everything else is the application's problem.

That sounds like a flaw until you consider real-time traffic. A video call can't wait 200 milliseconds for a retransmitted audio packet. Skipping the lost frame and keeping the conversation flowing beats stalling every time.

How TCP and UDP Work on the Wire

A packet capture shows the difference plainly. A TCP connection announces itself with three packets before any application data flows:

# Capture traffic on a Linux host
$ tcpdump -i eth0 -n port 443
12:04:11.223014 IP 192.168.1.24.51822 > 93.184.216.34.443: Flags [S], seq 812345678
12:04:11.241872 IP 93.184.216.34.443 > 192.168.1.24.51822: Flags [S.], seq 402117733, ack 812345679
12:04:11.241915 IP 192.168.1.24.51822 > 93.184.216.34.443: Flags [.], ack 402117734

SYN, SYN-ACK, ACK. That's the handshake. A UDP exchange has no equivalent moment, just datagrams leaving the host, each one addressed and sent independently.

Key Differences at a Glance

The practical differences come down to a handful of properties:

Property

TCP

UDP

Connection

Handshake required, stateful

None, stateless

Reliability

Guaranteed delivery with retransmission

Best effort, silent loss

Ordering

In-order byte stream

No ordering

Data model

Stream with no message boundaries

Discrete datagrams

Header size

20 to 60 bytes

8 bytes

Congestion control

Built in (CUBIC, BBR)

None unless the app adds it

First-byte latency

Handshake round trips plus TLS

Zero setup

Typical uses

Web, email, file transfer, APIs

DNS, VoIP, gaming, streaming

Seeing Them on a Live System

Ports are how both protocols multiplex traffic on a single machine. To see which services on a Linux host use which protocol:

# List TCP and UDP listeners
$ ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
udp   UNCONN 0      0      0.0.0.0:5353       0.0.0.0:*         users:(("avahi-daemon",pid=901))
tcp   LISTEN 0      128    0.0.0.0:22         0.0.0.0:*         users:(("sshd",pid=812))

The Netid column settles it. SSH listens on TCP, the mDNS discovery service on UDP. Most real servers run a mix of both.

QUIC blurs the line in a useful way. Since QUIC runs over UDP, you can test whether a site supports it with curl:

# Ask curl to negotiate QUIC, which rides on UDP
$ curl -I --http3 https://quic.nginx.org
HTTP/3 200
server: nginx/1.25.4

An HTTP/3 200 response means the transfer used QUIC over UDP, with TCP-style reliability layered on top.

When to Use Each

Choose TCP, or HTTP/3, whenever correctness beats latency: web pages, file transfers, email, APIs, payments, and database connections. Choose UDP when data goes stale fast: voice, live video, gaming, sensor telemetry, and DNS lookups, where a fresh retry costs less than retransmitting old data.

Never assume TCP's guarantees on a raw UDP path. If a UDP application needs ordering or delivery confirmation, the application has to build it itself, and that's a serious engineering lift.

TCP, UDP, and Where the Internet Is Heading

The clean binary between the two is softening. QUIC, the transport behind HTTP/3, runs over UDP yet delivers TCP-like reliability, mandatory TLS 1.3 encryption, per-stream ordering, and no head-of-line blocking between streams. It also survives IP address changes, which mobile users notice every time a device hops from Wi-Fi to cellular.

TCP vs UDP still remains the foundation for understanding the rest of the stack. From here it makes sense to look at how routers and switches move these packets across networks, or how public and private IP addressing decides where they can travel in the first place.

Then test your own machine. Run a capture, watch which protocol each app actually uses, and the distinction stops being theory.