TCP vs UDP Guide

TCP vs UDP at a Glance

FeatureTCPUDP
ConnectionConnection-oriented (3-way handshake)Connectionless
ReliabilityGuaranteed delivery with retransmitBest-effort, no guarantee
OrderingIn-order delivery guaranteedNo ordering guarantee
Error checkingChecksum + ACK + retransmitChecksum only (optional)
Flow controlYes (sliding window)No
Congestion controlYes (CUBIC, BBR, etc.)No
Header size20โ€“60 bytes8 bytes
SpeedSlower (overhead)Faster (low overhead)
Broadcast/MulticastNoYes

TCP Three-Way Handshake

Client Server | | |-------- SYN (seq=x) ---->| Client initiates | | |<-- SYN-ACK (seq=y,ack=x+1) -- Server acknowledges | | |---- ACK (ack=y+1) ------>| Connection established | | # Connection teardown (FIN-ACK-FIN-ACK)

Use Cases

ProtocolBest ForExamples
TCPData integrity criticalHTTP/HTTPS, SSH, FTP, email (SMTP/IMAP), databases
UDPLow latency, loss-tolerantDNS, DHCP, VoIP, video streaming, online gaming, QUIC

Go TCP Server Example

// TCP Server ln, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } for { conn, err := ln.Accept() if err != nil { continue } go func(c net.Conn) { defer c.Close() buf := make([]byte, 1024) n, _ := c.Read(buf) c.Write(buf[:n]) // echo back }(conn) } // UDP Server addr, _ := net.ResolveUDPAddr("udp", ":9090") conn, _ := net.ListenUDP("udp", addr) defer conn.Close() buf := make([]byte, 1024) for { n, remoteAddr, _ := conn.ReadFromUDP(buf) conn.WriteToUDP(buf[:n], remoteAddr) }

QUIC โ€” Modern Alternative

AspectDetail
TransportBuilt on UDP, adds reliability in user space
Handshake0-RTT or 1-RTT (vs TCP+TLS 2-3 RTT)
MultiplexingNo head-of-line blocking (unlike HTTP/2+TCP)
MigrationConnection survives IP changes (mobile roaming)
Used byHTTP/3, Google services, Cloudflare