TCP vs UDP & Transport Protocols
📖 Concept
At the transport layer, two protocols dominate: TCP (Transmission Control Protocol) and UDP (User Datagram Protocol). Understanding when to use each is crucial for system design, especially for real-time systems, streaming, and gaming.
TCP vs UDP Comparison
| Feature | TCP | UDP |
|---|---|---|
| Connection | Connection-oriented (3-way handshake) | Connectionless |
| Reliability | Guaranteed delivery, ordering | No guarantee — packets can be lost |
| Ordering | In-order delivery | No ordering |
| Speed | Slower (overhead for reliability) | Faster (minimal overhead) |
| Flow control | Yes (sliding window) | No |
| Congestion control | Yes (slow start, AIMD) | No |
| Use cases | Web, Email, File transfer, APIs | Video streaming, Gaming, DNS, VoIP |
| Header size | 20-60 bytes | 8 bytes |
The TCP 3-Way Handshake
Every TCP connection starts with:
- SYN: Client sends "I want to connect" (sequence number X)
- SYN-ACK: Server responds "OK, I acknowledge X+1, my number is Y"
- ACK: Client confirms "I acknowledge Y+1"
This adds 1 round-trip of latency before any data is sent (called connection establishment overhead).
When to Use Each
Use TCP When:
- Data integrity matters — file transfers, database queries, API calls
- Ordering matters — financial transactions, message delivery
- You need reliability — email (SMTP), web pages (HTTP)
Use UDP When:
- Speed > reliability — live video streaming, online gaming
- Some packet loss is acceptable — VoIP (a dropped audio frame is better than lag)
- You need multicast/broadcast — service discovery, DHCP
- Small, quick messages — DNS queries (single packet, no handshake needed)
Modern Protocols
- QUIC (used by HTTP/3): Built on UDP but adds TCP-like reliability with lower latency. It eliminates head-of-line blocking and supports connection migration (switching from WiFi to cellular without reconnecting).
- WebRTC: Uses UDP for real-time audio/video with custom reliability layers on top.
Pro tip: In interviews, if you're designing a real-time system (chat, gaming, video), mention UDP + application-level reliability. For everything else, TCP (via HTTP) is the default.
💻 Code Example
1// ============================================2// TCP vs UDP — Conceptual Comparison3// ============================================45// ---------- TCP-like Communication (Reliable) ----------67class TCPConnection {8 constructor(destination) {9 this.destination = destination;10 this.sequenceNumber = 0;11 this.ackBuffer = new Map(); // Track sent packets awaiting acknowledgment12 this.receiveBuffer = []; // Buffer for in-order delivery13 this.connected = false;14 this.retryTimeout = 1000; // 1 second15 this.maxRetries = 3;16 }1718 // 3-way handshake19 async connect() {20 console.log(`[TCP] Step 1: Sending SYN to \${this.destination}`);21 const synAck = await this.sendAndWait({ type: 'SYN', seq: this.sequenceNumber });2223 console.log(`[TCP] Step 2: Received SYN-ACK (ack=\${synAck.ack})`);24 await this.send({ type: 'ACK', ack: synAck.seq + 1 });2526 console.log('[TCP] Step 3: Connection ESTABLISHED');27 this.connected = true;28 this.sequenceNumber = synAck.ack;29 }3031 // Reliable send with acknowledgment and retry32 async sendReliable(data) {33 if (!this.connected) throw new Error('Not connected');3435 const packet = {36 seq: this.sequenceNumber++,37 data,38 timestamp: Date.now(),39 };4041 for (let attempt = 1; attempt <= this.maxRetries; attempt++) {42 console.log(`[TCP] Sending packet seq=\${packet.seq} (attempt \${attempt})`);4344 try {45 const ack = await this.sendAndWait(packet);46 console.log(`[TCP] ✅ Packet seq=\${packet.seq} acknowledged`);47 return ack;48 } catch (e) {49 console.log(`[TCP] ⏳ Timeout for seq=\${packet.seq}, retrying...`);50 // Exponential backoff51 await this.sleep(this.retryTimeout * attempt);52 }53 }54 throw new Error(`[TCP] ❌ Failed after \${this.maxRetries} retries`);55 }5657 async sendAndWait(packet) {58 return new Promise((resolve, reject) => {59 setTimeout(() => {60 // Simulate network — 90% success rate61 if (Math.random() < 0.9) {62 resolve({ ack: packet.seq + 1, seq: Math.floor(Math.random() * 1000) });63 } else {64 reject(new Error('Timeout'));65 }66 }, 100);67 });68 }6970 async send(packet) {71 return new Promise(resolve => setTimeout(resolve, 50));72 }7374 sleep(ms) {75 return new Promise(resolve => setTimeout(resolve, ms));76 }77}7879// ---------- UDP-like Communication (Fast, Unreliable) ----------8081class UDPSocket {82 constructor(destination) {83 this.destination = destination;84 this.packetsSent = 0;85 this.packetsDropped = 0;86 }8788 // Fire-and-forget — no handshake, no acknowledgment89 send(data) {90 this.packetsSent++;9192 // Simulate 5% packet loss (normal for UDP)93 if (Math.random() < 0.05) {94 this.packetsDropped++;95 console.log(`[UDP] 📦 Packet #\${this.packetsSent} DROPPED (lost in transit)`);96 return false; // Packet lost — caller doesn't know unless they check97 }9899 console.log(`[UDP] 📦 Packet #\${this.packetsSent} delivered to \${this.destination}`);100 return true; // No guarantee the receiver actually got it101 }102103 getStats() {104 return {105 sent: this.packetsSent,106 dropped: this.packetsDropped,107 deliveryRate: ((this.packetsSent - this.packetsDropped) / this.packetsSent * 100).toFixed(1) + '%',108 };109 }110}111112// ---------- When to Use Which ----------113114// ❌ BAD: Using UDP for file transfer (data corruption)115function badFileTransferUDP(file) {116 const udp = new UDPSocket('storage-server');117 for (const chunk of file.chunks) {118 udp.send(chunk); // Some chunks WILL be lost!119 }120 // File arrives corrupted — missing chunks121}122123// ✅ GOOD: Using TCP for file transfer (guaranteed delivery)124async function goodFileTransferTCP(file) {125 const tcp = new TCPConnection('storage-server');126 await tcp.connect();127 for (const chunk of file.chunks) {128 await tcp.sendReliable(chunk); // Every chunk verified129 }130 // File arrives complete and in order131}132133// ✅ GOOD: Using UDP for live video streaming134function liveVideoStreamUDP(videoFrames) {135 const udp = new UDPSocket('viewer-client');136 for (const frame of videoFrames) {137 udp.send(frame);138 // If a frame is dropped, just show the next one139 // Re-requesting the old frame would cause visible lag140 }141}142143// Demo144console.log('--- UDP Streaming Demo ---');145const udp = new UDPSocket('viewer');146for (let i = 0; i < 20; i++) {147 udp.send(`frame_\${i}`);148}149console.log('Stats:', udp.getStats());
🏋️ Practice Exercise
Handshake Trace: Draw the complete TCP 3-way handshake with sequence numbers (SYN seq=100, SYN-ACK, ACK). Then draw a 4-step connection teardown (FIN/ACK).
Protocol Selection: For each scenario, choose TCP or UDP and explain why: (a) Real-time multiplayer game, (b) Email sending, (c) Live sports scoreboard, (d) File backup to cloud, (e) IoT sensor heartbeat.
Latency Calculation: A client in London connects to a server in New York (RTT = 80ms). Calculate the minimum time to establish a TCP connection and send the first data byte. Compare with UDP.
QUIC Research: Research the QUIC protocol (HTTP/3). Explain how it achieves TCP-like reliability over UDP and why it's faster for web browsing.
Head-of-Line Blocking: Explain the head-of-line blocking problem in TCP and how HTTP/2 multiplexing partially solves it. Why does HTTP/3 (QUIC) solve it completely?
⚠️ Common Mistakes
Assuming UDP is always faster — UDP is faster for small, independent messages. For large data transfers, TCP's flow control and congestion avoidance can actually be more efficient than naive UDP with application-level retry logic.
Forgetting the TCP handshake latency cost — every new TCP connection adds 1 RTT (round-trip time). For mobile users on high-latency networks (200ms RTT), this means 200ms before any data flows. Use connection pooling or HTTP/2 keep-alive to amortize this cost.
Using TCP for real-time audio/video — a single lost packet in TCP blocks ALL subsequent data (head-of-line blocking). For real-time media, UDP with application-level loss concealment is always better.
Not considering middle devices — firewalls, NATs, and proxies often block or interfere with non-standard UDP traffic. This is why WebRTC has complex ICE/STUN/TURN mechanisms to work around network restrictions.
💼 Interview Questions
🎤 Mock Interview
Practice a live interview for TCP vs UDP & Transport Protocols