Chapter 1: How the Internet Works

Understanding the internet's fundamental protocols is essential for system design. This chapter covers the full stack from physical layer to application protocols, with real-world performance numbers, architectural trade-offs, and interview-ready explanations.

1.1 The OSI Model & TCP/IP Model

Why Layered Architecture?

The internet uses a layered architecture where each layer provides services to the layer above and consumes services from the layer below. This design principle enables:

  • Separation of concerns: Physical transmission details are hidden from application developers
  • Interoperability: Different implementations can work together as long as they follow layer contracts
  • Evolution: Layers can be upgraded independently (e.g., IPv4 β†’ IPv6 without changing HTTP)
  • Fault isolation: Problems at one layer don't cascade to all layers

Alternative considered and rejected: A monolithic design where each application handles its own physical transmission, error correction, routing, etc. This would require every app to reinvent the wheel and make protocol evolution impossible.

The Two Models

The OSI (Open Systems Interconnection) model is a theoretical 7-layer reference model. The TCP/IP model is the practical 4-layer implementation the internet actually uses.

graph LR subgraph "OSI Model (7 Layers)" A7["7. Application
(HTTP, FTP, SMTP)"] A6["6. Presentation
(TLS, encoding)"] A5["5. Session
(connections)"] A4["4. Transport
(TCP, UDP)"] A3["3. Network
(IP, routing)"] A2["2. Data Link
(Ethernet, WiFi)"] A1["1. Physical
(cables, signals)"] end subgraph "TCP/IP Model (4 Layers)" B4["4. Application
(HTTP, DNS, SSH)"] B3["3. Transport
(TCP, UDP)"] B2["2. Internet
(IP, ICMP)"] B1["1. Link
(Ethernet, WiFi)"] end A7 --> B4 A6 --> B4 A5 --> B4 A4 --> B3 A3 --> B2 A2 --> B1 A1 --> B1
OSI Layer TCP/IP Layer Function Examples Real-World Impact
7. Application Application End-user protocols and data representation HTTP, DNS, SMTP, FTP, SSH What you code against
6. Presentation Data encoding, encryption, compression TLS/SSL, JPEG, MPEG, ASCII TLS negotiation adds ~1 RTT
5. Session Connection management, sessions NetBIOS, RPC, session cookies Often merged into application
4. Transport Transport End-to-end reliability, flow control TCP, UDP, SCTP TCP handshake = 1 RTT (~50-200ms)
3. Network Internet Routing, addressing, packet forwarding IPv4, IPv6, ICMP, routing protocols Routing adds ~10-50ms per hop
2. Data Link Link Node-to-node data transfer, MAC addressing Ethernet, WiFi (802.11), PPP WiFi latency ~2-5ms, Ethernet ~0.1ms
1. Physical Raw bit transmission over physical medium Cables, fiber, radio waves, voltage levels Speed of light in fiber: ~200km/ms

What Happens at Each Layer

When you send an HTTP request, data flows down the stack on the sender side and up the stack on the receiver side:

sequenceDiagram participant App as Application participant Trans as Transport participant Net as Network participant LnkLayer as LnkLayer Layer participant Wire as Physical Wire participant RLink as Server LnkLayer participant RNet as Server Network participant RTrans as Server Transport participant RApp as Web Server App->>Trans: GET /api HTTP/1.1 Trans->>Net: TCP segment Net->>LnkLayer: IP packet LnkLayer->>Wire: Ethernet frame as bits Wire->>RLink: Bits arrive RLink->>RNet: Strip Ethernet, pass up RNet->>RTrans: Strip IP, pass up RTrans->>RApp: Strip TCP, pass up
Key Takeaway

Encapsulation: Each layer adds its own header (and sometimes trailer) to the data from the layer above. This is like putting a letter in an envelope, then putting that envelope in a package, then putting that package on a truck. Each layer only reads its own header.

Interview Signal

When asked "What happens when you type google.com?" candidates who start with "DNS lookup" miss the point. Strong answers mention the full stack: Application (HTTP), Transport (TCP handshake), Network (IP routing), Link (ARP, MAC addresses), and Physical (signals on wire). Bonus points for mentioning encapsulation and which headers are added at each layer.

1.2 DNS (Domain Name System)

What is DNS?

DNS is the internet's phone book. It translates human-readable domain names (google.com) into IP addresses (142.250.185.46). Without DNS, you'd need to memorize IP addresses for every website.

Typical DNS lookup time: 20-120ms (cached: <1ms, uncached: 50-200ms)

DNS Hierarchy

DNS is a distributed hierarchical system with three levels:

graph TD Root["Root Servers
(13 worldwide, . root)"] TLD_com[".com TLD Server"] TLD_org[".org TLD Server"] TLD_net[".net TLD Server"] Auth_google["google.com
Authoritative Server"] Auth_example["example.org
Authoritative Server"] Root --> TLD_com Root --> TLD_org Root --> TLD_net TLD_com --> Auth_google TLD_org --> Auth_example style Root fill:#ff6b6b,color:#1a1a2e style TLD_com fill:#4ecdc4,color:#1a1a2e style TLD_org fill:#4ecdc4,color:#1a1a2e style TLD_net fill:#4ecdc4,color:#1a1a2e style Auth_google fill:#95e1d3,color:#1a1a2e style Auth_example fill:#95e1d3,color:#1a1a2e
  1. Root servers: 13 root server clusters (a.root-servers.net to m.root-servers.net) that know where TLD servers are
  2. TLD (Top-Level Domain) servers: Manage .com, .org, .net, etc. Operated by registries like Verisign
  3. Authoritative name servers: The final authority for a domain, usually managed by hosting providers or domain owners

Recursive vs Iterative Resolution

When you type "www.google.com", your computer doesn't query all these servers. Your ISP's DNS resolver does the work:

sequenceDiagram participant Client as Your Computer participant Resolver as DNS Resolver ISP participant Root as Root Server participant TLD as .com TLD Server participant Auth as google.com Authoritative Note over Client,Resolver: Recursive Query Client->>Resolver: What is www.google.com? Note over Resolver,Auth: Iterative Queries Resolver->>Root: What is www.google.com? Root-->>Resolver: Ask .com server at 192.5.6.30 Resolver->>TLD: What is www.google.com? TLD-->>Resolver: Ask google.com server at 216.239.32.10 Resolver->>Auth: What is www.google.com? Auth-->>Resolver: 142.250.185.46 (A record) Resolver-->>Client: 142.250.185.46 Note over Client: Browser connects to 142.250.185.46:443

Recursive query: Client asks resolver to do all the work and return final answer

Iterative query: Resolver asks each server "Who should I ask next?" and follows the chain

DNS Record Types

Record Type Purpose Example Use Case
A Maps domain to IPv4 address example.com β†’ 93.184.216.34 Most common, points to web server
AAAA Maps domain to IPv6 address example.com β†’ 2606:2800:220:1:: IPv6 support
CNAME Alias to another domain www.example.com β†’ example.com Subdomains, CDN routing
MX Mail server for domain example.com β†’ mail.example.com (priority 10) Email routing
NS Authoritative name server example.com β†’ ns1.hostingprovider.com DNS delegation
TXT Arbitrary text data "v=spf1 include:_spf.google.com ~all" SPF, DKIM, domain verification
SRV Service location _sip._tcp.example.com β†’ sipserver:5060 Service discovery (SIP, XMPP)
PTR Reverse DNS (IP β†’ domain) 34.216.184.93.in-addr.arpa β†’ example.com Email validation, logging
CAA Certificate authority authorization example.com β†’ letsencrypt.org Restrict which CAs can issue certs

DNS Caching & TTL

DNS responses include a TTL (Time To Live) value that tells resolvers how long to cache the result:

  • Low TTL (60-300s): Fast updates, more DNS queries, higher load
  • High TTL (3600-86400s): Fewer queries, slower updates, better performance

Caching happens at multiple levels: browser cache β†’ OS cache β†’ ISP resolver cache β†’ authoritative server

Advanced DNS Techniques

DNS Load Balancing

Return multiple A records with different IPs, rotated on each query (round-robin DNS):

example.com.  300  IN  A  93.184.216.34
example.com.  300  IN  A  93.184.216.35
example.com.  300  IN  A  93.184.216.36

Limitation: Doesn't account for server health or load. Use dedicated load balancers for production.

GeoDNS

Return different IPs based on client location. Example: US clients get us-east-1 server, EU clients get eu-west-1 server. Reduces latency by ~50-200ms.

DNS Failover

Health check primary server; if down, return secondary IP. TTL must be low (60-300s) for fast failover.

DNS-over-HTTPS (DoH) & DNS-over-TLS (DoT)

Encrypt DNS queries to prevent ISP snooping and man-in-the-middle attacks. DoH uses HTTPS (port 443), DoT uses TLS (port 853). Supported by Chrome, Firefox, Cloudflare (1.1.1.1), Google (8.8.8.8).

What Happens When You Type "google.com"?

sequenceDiagram participant User as User Browser participant DNS as DNS Resolver participant TCP as TCP Stack participant Server as google.com 142.250.185.46 Note over User: User types "google.com" User->>User: Check browser DNS cache alt Cache Hit Note over User: Use cached IP (142.250.185.46) else Cache Miss User->>DNS: DNS query for google.com Note over DNS: Check resolver cache alt Cache Hit DNS-->>User: 142.250.185.46 (cached) else Cache Miss Note over DNS: Recursive resolution
(root β†’ TLD β†’ auth) DNS-->>User: 142.250.185.46 (fresh) end end Note over User,TCP: TCP 3-way handshake User->>Server: SYN Server-->>User: SYN-ACK User->>Server: ACK Note over User,Server: TLS handshake (1-2 RTT) User->>Server: ClientHello Server-->>User: ServerHello, Certificate User->>Server: Key Exchange, Finished Note over User,Server: HTTP request User->>Server: GET / HTTP/1.1 Server-->>User: 200 OK (HTML) Note over User: Browser renders page
Key Takeaway

DNS is on the critical path: The first time a user visits your site, DNS lookup adds 20-120ms. Use low TTLs for flexibility (but more queries) or high TTLs for performance (but slower updates). CDNs like Cloudflare offer 1.1.1.1 resolver with <10ms lookups globally.

Interview Signal

Strong candidates know DNS caching is multi-level (browser, OS, ISP) and can explain why TTL matters for blue-green deployments. Bonus points for mentioning DNS prefetching (<link rel="dns-prefetch">) to hide DNS latency.

1.3 TCP (Transmission Control Protocol)

What is TCP?

TCP is a reliable, ordered, connection-oriented transport protocol. It guarantees that data arrives in the correct order without errors, retransmitting lost packets as needed. Used by HTTP, HTTPS, SSH, email protocols.

TCP handshake cost: 1 RTT (~50-200ms for intercontinental connections, ~1-20ms within region)

TCP 3-Way Handshake (Connection Establishment)

Before sending data, TCP establishes a connection using a 3-way handshake:

sequenceDiagram participant Client participant Server Note over Client,Server: Connection Establishment (1 RTT) Client->>Server: SYN (seq=1000) Note over Client: State: SYN-SENT Note over Server: State: LISTEN β†’ SYN-RECEIVED Server-->>Client: SYN-ACK (seq=5000, ack=1001) Note over Client: State: ESTABLISHED Client->>Server: ACK (seq=1001, ack=5001) Note over Server: State: ESTABLISHED Note over Client,Server: Connection Ready
Data transfer can begin
  1. SYN: Client sends synchronization packet with initial sequence number (ISN)
  2. SYN-ACK: Server acknowledges client's ISN and sends its own ISN
  3. ACK: Client acknowledges server's ISN. Connection established.

Why 3 steps instead of 2? To prevent old duplicate SYNs from establishing unwanted connections. Both sides must agree on initial sequence numbers.

TCP 4-Way Connection Termination

Closing a TCP connection requires 4 messages (can be optimized to 3):

sequenceDiagram participant Client participant Server Note over Client,Server: Connection Termination Client->>Server: FIN (seq=1500) Note over Client: State: FIN-WAIT-1 Server-->>Client: ACK (ack=1501) Note over Client: State: FIN-WAIT-2 Note over Server: State: CLOSE-WAIT
(Server can still send data) Server->>Client: FIN (seq=6000) Note over Server: State: LAST-ACK Note over Client: State: TIME-WAIT Client-->>Server: ACK (ack=6001) Note over Server: State: CLOSED Note over Client: Wait 2*MSL (60-240s)
then CLOSED

Why TIME-WAIT? Client waits 2*MSL (Maximum Segment Lifetime, typically 30-120s) to ensure the final ACK isn't lost. If server doesn't receive it, server retransmits FIN, and client can re-send ACK.

TCP Sliding Window (Flow Control)

TCP uses a sliding window to send multiple packets without waiting for individual ACKs. The window size is advertised by the receiver based on its buffer space.

graph LR subgraph "Sender's View" A[Sent & ACKed
bytes 1-1000] B[Sent, awaiting ACK
bytes 1001-1500] C[Ready to send
bytes 1501-2000] D[Not yet sendable
bytes 2001+] end style A fill:#95e1d3,color:#1a1a2e style B fill:#ffd93d,color:#1a1a2e style C fill:#6bcf7f,color:#1a1a2e style D fill:#ddd,color:#1a1a2e Note1["Window = 1000 bytes
(bytes 1001-2000)"] Note1 -.-> B Note1 -.-> C

As ACKs arrive, the window slides forward, allowing more data to be sent. This improves throughput by keeping the pipe full.

TCP Congestion Control

TCP adjusts its sending rate based on network congestion. Key algorithms:

Congestion Window (cwnd) States

stateDiagram-v2 [*] --> SlowStart: Connection starts SlowStart --> CongestionAvoidance: cwnd >= ssthresh CongestionAvoidance --> FastRecovery: 3 duplicate ACKs CongestionAvoidance --> SlowStart: Timeout FastRecovery --> CongestionAvoidance: New ACK received FastRecovery --> SlowStart: Timeout note right of SlowStart: Exponential growth, cwnd doubles per RTT note right of CongestionAvoidance: Linear growth, cwnd += 1 per RTT note right of FastRecovery: Halve cwnd, Fast retransmit lost packet
  1. Slow Start: Begin with small cwnd (typically 10 segments = 14KB). Double cwnd every RTT until reaching ssthresh (slow start threshold) or packet loss occurs.
    • RTT 1: 10 segments
    • RTT 2: 20 segments
    • RTT 3: 40 segments (exponential growth)
  2. Congestion Avoidance: After ssthresh, increase cwnd by 1 segment per RTT (linear growth). Continue until packet loss.
  3. Fast Retransmit: If 3 duplicate ACKs received, immediately retransmit the lost packet without waiting for timeout. This indicates packet loss, not network death.
  4. Fast Recovery: After fast retransmit, set ssthresh = cwnd / 2, set cwnd = ssthresh, and enter congestion avoidance. This avoids slow start's performance hit.

Real numbers: For a 100ms RTT connection with 10 Mbps bandwidth, slow start takes ~4 RTTs (400ms) to ramp up. This is why TCP is slow for short-lived connections.

Nagle's Algorithm

Nagle's algorithm reduces small packet overhead by buffering small writes until either:

  • Enough data accumulated to fill a full segment (MSS, typically 1460 bytes)
  • All previously sent data has been acknowledged

Problem: Adds latency (up to 1 RTT) for interactive applications like SSH or gaming.

Solution: Disable Nagle with TCP_NODELAY socket option. HTTP/2 and gRPC do this by default.

Head-of-Line Blocking

TCP delivers data in order. If packet 5 is lost, packets 6, 7, 8 must wait for packet 5 to be retransmitted, even if they arrived successfully. This is head-of-line blocking.

sequenceDiagram participant Sender participant Network participant Receiver Sender->>Network: Packet 1 Sender->>Network: Packet 2 Sender->>Network: Packet 3 (lost!) Sender->>Network: Packet 4 Sender->>Network: Packet 5 Network->>Receiver: Packet 1 Network->>Receiver: Packet 2 Network->>Receiver: Packet 4 (buffered) Network->>Receiver: Packet 5 (buffered) Note over Receiver: Cannot deliver 4, 5
until 3 arrives Sender->>Network: Packet 3 (retransmitted) Network->>Receiver: Packet 3 Note over Receiver: Now deliver 3, 4, 5
in order

Impact: On lossy networks (1% loss), TCP throughput can drop by 50%. HTTP/2 multiplexing over a single TCP connection amplifies this problem. HTTP/3 solves it by using QUIC over UDP with per-stream ordering.

Key Takeaway

TCP guarantees reliability but adds latency: 3-way handshake (1 RTT), slow start (3-5 RTTs to full speed), head-of-line blocking (1 RTT per loss). For low-latency applications, consider UDP + custom reliability (QUIC) or HTTP/3.

Interview Signal

Candidates who mention "TCP is reliable" without explaining the cost (handshake, congestion control, HOL blocking) miss nuance. Strong answers quantify latency (1 RTT handshake, 200ms for US-Europe) and explain when TCP's guarantees aren't worth the cost (real-time video, gaming).

1.4 UDP (User Datagram Protocol) & QUIC

What is UDP?

UDP is a connectionless, unreliable transport protocol. It sends packets (datagrams) without handshakes, acknowledgments, or retransmissions. Minimal overhead, but no guarantees.

Latency: No connection setup. First packet can be sent immediately (0 RTT).

TCP vs UDP Comparison

Feature TCP UDP
Connection Connection-oriented (3-way handshake) Connectionless (no handshake)
Reliability Guaranteed delivery, retransmission Best effort, no guarantees
Ordering In-order delivery guaranteed Packets may arrive out of order
Error Checking Checksum + retransmission Checksum only (optional)
Flow Control Sliding window None
Congestion Control Yes (slow start, AIMD) None (app must handle)
Overhead 20+ bytes header + state tracking 8 bytes header, stateless
Speed Slower (handshake, retransmissions) Faster (no handshake, no retransmit)
Use Cases HTTP, HTTPS, email, file transfer DNS, video streaming, gaming, VoIP

When to Use UDP

UDP is ideal when:

  • Low latency matters more than reliability: Gaming (lost frame is OK, stale frame is not), live video streaming
  • Small request-response: DNS (single packet query + response, faster than TCP handshake)
  • Real-time communication: VoIP (Zoom, Skype), video conferencing (dropped packet = brief glitch, not worth delaying)
  • Broadcast/multicast: IPTV, service discovery
  • Custom reliability: When you want to build your own congestion control (QUIC, game engines)

QUIC: UDP's Evolution

QUIC (Quick UDP Internet Connections) is a modern transport protocol built on UDP. It combines UDP's low latency with TCP-like reliability, plus built-in encryption (TLS 1.3).

QUIC Advantages over TCP

  1. 0-RTT Connection Establishment: First request sent immediately (vs TCP's 1-RTT handshake + 1-RTT TLS = 2 RTT total)
    sequenceDiagram participant Client participant Server Note over Client,Server: QUIC 0-RTT (Resumed Connection) Client->>Server: QUIC Initial + TLS ClientHello + HTTP Request Server-->>Client: QUIC Handshake + TLS ServerHello + HTTP Response Note over Client,Server: Total: 1 RTT (data sent on first packet!) Note over Client,Server: vs TCP + TLS 1.3 Client->>Server: TCP SYN Server-->>Client: TCP SYN-ACK Client->>Server: TCP ACK + TLS ClientHello Server-->>Client: TLS ServerHello Client->>Server: HTTP Request Server-->>Client: HTTP Response Note over Client,Server: Total: 2-3 RTT
  2. No Head-of-Line Blocking: QUIC supports multiple independent streams over a single connection. Lost packet in stream 1 doesn't block stream 2.
  3. Connection Migration: Connection identified by ID (not 4-tuple of IP:port). Switch from WiFi to cellular without reconnecting.
  4. Improved Congestion Control: Congestion control in userspace (not kernel), easier to update algorithms.
  5. Built-in Encryption: All QUIC packets are encrypted (TLS 1.3 mandatory). No plaintext metadata.

QUIC Adoption

  • HTTP/3 uses QUIC (replacing TCP)
  • Google (YouTube, Search, Gmail), Facebook, Cloudflare use QUIC
  • ~25% of internet traffic uses QUIC (2024 estimate)
  • Supported by Chrome, Firefox, Edge, Safari (partial)
Key Takeaway

UDP sacrifices reliability for speed. TCP's 3-way handshake + TLS = 2 RTT (100-400ms for intercontinental) before sending data. UDP + QUIC = 0-1 RTT. For real-time apps, this matters more than perfect delivery.

Interview Signal

Weak answers: "UDP is faster because it's unreliable." Strong answers: "UDP avoids TCP's 1-RTT handshake and head-of-line blocking. QUIC layers reliability on UDP while keeping 0-RTT connection setup and per-stream ordering. This is why YouTube uses QUICβ€”lost packet in one video chunk doesn't block the next chunk."

1.5 IP (Internet Protocol): IPv4 & IPv6

What is IP?

IP is the network layer protocol responsible for addressing and routing packets across networks. It's connectionless and best-effort (no guarantees). TCP/UDP sit on top of IP.

IPv4 vs IPv6

Feature IPv4 IPv6
Address Size 32 bits (4 bytes) 128 bits (16 bytes)
Format Dotted decimal: 192.168.1.1 Hex colon: 2001:0db8::1
Address Space 4.3 billion (~4.3Γ—10⁹) 340 undecillion (~3.4Γ—10³⁸)
Header Size 20-60 bytes (variable) 40 bytes (fixed)
Fragmentation Routers can fragment packets Only sender fragments (Path MTU Discovery)
Checksum Header checksum required No checksum (relies on upper layers)
NAT Required (address exhaustion) Not needed (enough addresses)
Configuration DHCP or manual SLAAC (auto-config) or DHCPv6
Broadcast Supported Replaced by multicast
Adoption ~97% of internet traffic (2024) ~40% and growing

IPv4 Address Classes (Historical)

Originally, IPv4 addresses were divided into classes:

  • Class A: 1.0.0.0 - 126.255.255.255 (8-bit network, 24-bit host = 16M hosts per network)
  • Class B: 128.0.0.0 - 191.255.255.255 (16-bit network, 16-bit host = 65K hosts)
  • Class C: 192.0.0.0 - 223.255.255.255 (24-bit network, 8-bit host = 254 hosts)

Obsolete: Replaced by CIDR (Classless Inter-Domain Routing) in 1993. Now use /prefix notation: 10.0.0.0/8 means first 8 bits are network, last 24 bits are host.

Subnetting Basics

CIDR notation: 192.168.1.0/24 means first 24 bits are network, last 8 bits are host.

  • /24 = 256 addresses (254 usable, 2 reserved: network address + broadcast)
  • /16 = 65,536 addresses
  • /8 = 16,777,216 addresses

Example: Split 10.0.0.0/16 into 4 subnets:

  • 10.0.0.0/18 (10.0.0.0 - 10.0.63.255)
  • 10.0.64.0/18 (10.0.64.0 - 10.0.127.255)
  • 10.0.128.0/18 (10.0.128.0 - 10.0.191.255)
  • 10.0.192.0/18 (10.0.192.0 - 10.0.255.255)

NAT (Network Address Translation)

NAT allows multiple devices on a private network (e.g., 192.168.1.x) to share a single public IP. The router translates private IPs to its public IP for outgoing traffic.

graph LR subgraph "Private Network (192.168.1.0/24)" Laptop["Laptop
192.168.1.10:5000"] Phone["Phone
192.168.1.11:5001"] end Router["NAT Router
Private: 192.168.1.1
Public: 203.0.113.5"] Internet["Internet
Server: 93.184.216.34:80"] Laptop -->|SRC: 192.168.1.10:5000
DST: 93.184.216.34:80| Router Phone -->|SRC: 192.168.1.11:5001
DST: 93.184.216.34:80| Router Router -->|SRC: 203.0.113.5:6000
DST: 93.184.216.34:80| Internet Router -->|SRC: 203.0.113.5:6001
DST: 93.184.216.34:80| Internet style Router fill:#ff6b6b,color:#1a1a2e

NAT Translation Table:

Private IP:Port Public IP:Port Destination
192.168.1.10:5000 203.0.113.5:6000 93.184.216.34:80
192.168.1.11:5001 203.0.113.5:6001 93.184.216.34:80

Problem with NAT: Breaks end-to-end connectivity. Inbound connections can't reach private IPs without port forwarding or NAT traversal (STUN, TURN).

Unicast vs Multicast vs Anycast

graph TD subgraph "Unicast (1-to-1)" U_Sender[Sender] -->|Single packet| U_Receiver[Receiver] end subgraph "Multicast (1-to-many)" M_Sender[Sender] -->|One packet,
duplicated by routers| M_R1[Receiver 1] M_Sender -->|Same packet| M_R2[Receiver 2] M_Sender -->|Same packet| M_R3[Receiver 3] end subgraph "Anycast (1-to-nearest)" A_Sender[Sender] -->|Routed to
nearest instance| A_Server1[Server 1
US-East] A_Sender -.->|Same IP, but
not chosen| A_Server2[Server 2
EU-West] end style U_Receiver fill:#95e1d3,color:#1a1a2e style M_R1 fill:#95e1d3,color:#1a1a2e style M_R2 fill:#95e1d3,color:#1a1a2e style M_R3 fill:#95e1d3,color:#1a1a2e style A_Server1 fill:#95e1d3,color:#1a1a2e style A_Server2 fill:#ddd,color:#1a1a2e
  • Unicast: One sender, one receiver. Standard IP addressing (most traffic).
  • Multicast: One sender, multiple receivers in a group. Used for IPTV, video conferencing, stock tickers. IPv4: 224.0.0.0/4, IPv6: ff00::/8.
  • Anycast: Multiple servers share the same IP. Routers send traffic to the nearest server (by BGP routing). Used by DNS root servers (13 IPs, 1000+ physical servers), CDNs (Cloudflare 1.1.1.1).

Private IP Ranges (RFC 1918)

These ranges are not routable on the public internet:

  • 10.0.0.0/8 (10.0.0.0 - 10.255.255.255) β€” Large enterprises, AWS VPCs
  • 172.16.0.0/12 (172.16.0.0 - 172.31.255.255) β€” Medium networks, Docker default
  • 192.168.0.0/16 (192.168.0.0 - 192.168.255.255) β€” Home routers, small offices
Key Takeaway

IPv4 exhaustion is real. IANA allocated the last /8 blocks in 2011. NAT is a workaround, not a solution. IPv6 adoption is growing (~40% of Google traffic in 2024), but IPv4 will coexist for decades. Dual-stack (IPv4 + IPv6) is the pragmatic approach.

Interview Signal

Strong candidates know why IPv6 is better (no NAT, larger address space, simpler header) but can explain why adoption is slow (legacy systems, NAT works "well enough"). Bonus points for mentioning anycast (Cloudflare 1.1.1.1 uses it) or IPv6-only mobile networks (T-Mobile, Verizon use 464XLAT).

1.6 HTTP/1.1

What is HTTP?

HTTP (Hypertext Transfer Protocol) is the application-layer protocol for the web. It defines how clients (browsers) and servers exchange requests and responses. HTTP/1.1 (RFC 2616, 1999) is the foundation of the modern web.

Request-Response Model

HTTP is a stateless, text-based protocol. Every interaction is a request-response pair:

Request (Client β†’ Server):
GET /api/users/123 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Authorization: Bearer eyJhbGc...

Response (Server β†’ Client):
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 87
Cache-Control: max-age=3600

{"id":123,"name":"Alice","email":"alice@example.com"}

HTTP Methods

Method Purpose Safe? Idempotent? Cacheable?
GET Retrieve resource Yes Yes Yes
POST Create resource, submit data No No Rarely
PUT Replace resource (full update) No Yes No
PATCH Partial update No No* No
DELETE Delete resource No Yes No
HEAD GET without body (headers only) Yes Yes Yes
OPTIONS Query supported methods (CORS) Yes Yes No
CONNECT Establish tunnel (HTTPS proxy) No No No
TRACE Echo request (debugging) Yes Yes No

Safe: Does not modify server state (read-only)
Idempotent: Multiple identical requests have same effect as one
*PATCH: Can be idempotent depending on implementation

HTTP Status Codes

Code Meaning Use Case
1xx Informational
100 Continue Client should continue with request body
101 Switching Protocols WebSocket upgrade
2xx Success
200 OK Standard success
201 Created Resource created (POST)
202 Accepted Async processing started
204 No Content Success, no response body (DELETE)
3xx Redirection
301 Moved Permanently URL changed forever (SEO signals)
302 Found Temporary redirect (common misuse of 301)
304 Not Modified Cache is still valid (ETag match)
307 Temporary Redirect Like 302, but preserves method
308 Permanent Redirect Like 301, but preserves method
4xx Client Error
400 Bad Request Invalid syntax or parameters
401 Unauthorized Authentication required
403 Forbidden Authenticated but not authorized
404 Not Found Resource doesn't exist
409 Conflict State conflict (version mismatch)
429 Too Many Requests Rate limit exceeded
5xx Server Error
500 Internal Server Error Generic server failure
502 Bad Gateway Upstream server error (proxy/LB)
503 Service Unavailable Overloaded or maintenance
504 Gateway Timeout Upstream server timeout

Important HTTP Headers

Request Headers

  • Host: Target domain (required in HTTP/1.1)
  • User-Agent: Client software (browser, bot)
  • Accept: Content types client can handle (application/json, text/html)
  • Authorization: Credentials (Bearer token, Basic auth)
  • Cookie: Session state
  • If-None-Match: ETag for conditional requests
  • Range: Partial content request (byte-range downloads)

Response Headers

  • Content-Type: MIME type (application/json, text/html)
  • Content-Length: Body size in bytes
  • Cache-Control: Caching policy (max-age=3600, no-cache)
  • ETag: Resource version hash (for conditional requests)
  • Set-Cookie: Set client cookie
  • Location: Redirect URL
  • Server: Server software (nginx, Apache)

HTTP/1.1 Features

Persistent Connections (Keep-Alive)

HTTP/1.0 opened a new TCP connection for each request. HTTP/1.1 defaults to persistent connections (Connection: keep-alive), reusing the same TCP connection for multiple requests.

Benefit: Avoids TCP handshake overhead (1 RTT saved per request after the first)

Default timeout: 5-15 seconds idle before server closes connection

HTTP Pipelining (Failed Experiment)

Pipelining allows sending multiple requests without waiting for responses (similar to TCP sliding window). Example: Send GET /a, GET /b, GET /c, then receive all responses in order.

Problem: Head-of-line blocking. If /a takes 5 seconds, /b and /c must wait, even if they're ready in 100ms.

Reality: Disabled in all major browsers due to buggy proxies and servers. HTTP/2 multiplexing solved this properly.

Connection Limits per Domain

Browsers limit concurrent connections per domain to prevent overwhelming servers:

  • HTTP/1.1: 6 connections per domain (Chrome, Firefox)
  • Workaround: Domain sharding (static1.example.com, static2.example.com) to get 6 connections Γ— N domains
  • HTTP/2: 1 connection per domain, unlimited streams (domain sharding is anti-pattern)
Key Takeaway

HTTP/1.1 bottlenecks: 6 connections per domain, head-of-line blocking (pipelining failure), text-based headers (overhead). For modern apps loading 100+ resources, HTTP/1.1 adds ~500-1000ms latency. HTTP/2 fixes this with multiplexing and binary framing.

Interview Signal

Candidates who say "HTTP is stateless" are correct but surface-level. Strong answers explain the trade-off: stateless design enables horizontal scaling (any server can handle any request) but requires cookies/tokens for session management. Bonus points for mentioning idempotency (PUT/DELETE are idempotent, POST is not) and why it matters for retry logic.

1.7 HTTP/2

What is HTTP/2?

HTTP/2 (RFC 7540, 2015) is a major revision designed to solve HTTP/1.1's performance bottlenecks. It maintains HTTP semantics (methods, status codes, headers) but completely changes the transport layer using a binary framing layer.

Adoption: ~50% of websites support HTTP/2 (2024). All modern browsers support it over TLS.

Binary Framing Layer

HTTP/1.1 is text-based (human-readable but inefficient). HTTP/2 encodes messages into binary frames, making parsing faster and less error-prone.

graph TD subgraph "HTTP/1.1 (Text)" Text["GET /api HTTP/1.1
Host: example.com
Accept: */*

"] end subgraph "HTTP/2 (Binary Frames)" Frame1[HEADERS Frame
Stream 1
:method: GET
:path: /api] Frame2[DATA Frame
Stream 1
Payload bytes] Frame3[HEADERS Frame
Stream 3
:method: POST] end Text -.-> |"Encoded into"| Frame1 Frame1 --> Frame2 Frame2 --> Frame3 style Text fill:#ffd93d,color:#1a1a2e style Frame1 fill:#95e1d3,color:#1a1a2e style Frame2 fill:#95e1d3,color:#1a1a2e style Frame3 fill:#95e1d3,color:#1a1a2e

Frame structure: Each frame has a 9-byte header (length, type, flags, stream ID) followed by a payload.

Multiplexing: Multiple Streams Over One Connection

HTTP/2's killer feature: send multiple request-response pairs concurrently over a single TCP connection without head-of-line blocking at the HTTP layer.

sequenceDiagram participant Browser participant Server Note over Browser,Server: Single TCP Connection Browser->>Server: HEADERS (Stream 1: GET /page.html) Browser->>Server: HEADERS (Stream 3: GET /style.css) Browser->>Server: HEADERS (Stream 5: GET /script.js) Note over Server: Processes in parallel Server-->>Browser: HEADERS+DATA (Stream 3: style.css) Server-->>Browser: HEADERS+DATA (Stream 5: script.js) Server-->>Browser: HEADERS+DATA (Stream 1: page.html) Note over Browser,Server: Responses arrive in any order
(no head-of-line blocking)

Key concepts:

  • Stream: Independent bidirectional message flow (one request-response pair)
  • Stream ID: Odd numbers = client-initiated, even numbers = server-initiated (server push)
  • Concurrency: 100+ streams can be active simultaneously on one connection
  • No more 6-connection limit: Only 1 connection needed per origin

Performance impact: Reduces page load time by 10-30% compared to HTTP/1.1, especially on high-latency connections.

Server Push

Server can proactively send resources to the client before they're requested. Example: Browser requests /index.html, server pushes /style.css and /script.js immediately.

sequenceDiagram participant Browser participant Server Browser->>Server: GET /index.html (Stream 1) Server->>Browser: PUSH_PROMISE (Stream 2: /style.css) Server->>Browser: PUSH_PROMISE (Stream 4: /script.js) Server-->>Browser: HEADERS+DATA (Stream 1: index.html) Server-->>Browser: HEADERS+DATA (Stream 2: style.css) Server-->>Browser: HEADERS+DATA (Stream 4: script.js) Note over Browser: Receives all resources
in 1 RTT instead of 2-3

Reality: Server push is tricky. If the client already has the resource cached, push wastes bandwidth. Chrome deprecated support in 2022. HTTP/3 has early hints (103 status) instead.

Header Compression (HPACK)

HTTP headers are repetitive (User-Agent, Cookie, Authorization sent on every request). HTTP/2 uses HPACK compression to reduce overhead.

How HPACK works:

  1. Static table: Common headers pre-defined (61 entries like :method GET = index 2)
  2. Dynamic table: Recently used headers stored in a shared table (LRU cache)
  3. Huffman encoding: Compress header values

Example:

Request 1 (full headers):
:method: GET
:path: /api/users
user-agent: Mozilla/5.0
cookie: session=abc123...

Request 2 (compressed):
:path: /api/orders (only path changes, rest references dynamic table)
Dynamic table index: 4, 5, 6 (method, user-agent, cookie)

Compression ratio: 80-95% reduction in header size. Critical for mobile networks where RTT is high (100-300ms).

Stream Prioritization

Clients can assign priorities to streams (dependencies + weights). Example: HTML (high priority) β†’ CSS (medium) β†’ images (low).

graph TD HTML[Stream 1
HTML
Weight: 256] -->|Depends on| Root[Root Stream] CSS[Stream 3
CSS
Weight: 220] -->|Depends on| HTML JS[Stream 5
JS
Weight: 220] -->|Depends on| HTML Img1[Stream 7
Image
Weight: 16] -->|Depends on| HTML Img2[Stream 9
Image
Weight: 16] -->|Depends on| HTML style HTML fill:#ff6b6b,color:#1a1a2e style CSS fill:#4ecdc4,color:#1a1a2e style JS fill:#4ecdc4,color:#1a1a2e style Img1 fill:#95e1d3,color:#1a1a2e style Img2 fill:#95e1d3,color:#1a1a2e

Reality: Many servers ignore priorities. CDNs (Cloudflare, Fastly) implement it, but origin servers often don't.

Flow Control

Each stream and the connection have flow control windows (similar to TCP). Receiver advertises how much data it can accept (WINDOW_UPDATE frames).

Purpose: Prevent fast sender from overwhelming slow receiver. Important for proxies handling many connections.

HTTP/1.1 vs HTTP/2 Comparison

Feature HTTP/1.1 HTTP/2
Encoding Text-based Binary frames
Multiplexing No (6 connections per domain) Yes (1 connection, unlimited streams)
Header Compression None HPACK (80-95% reduction)
Server Push No Yes (PUSH_PROMISE)
Prioritization No Yes (stream dependencies + weights)
Connections per Domain 6 (browser limit) 1
Head-of-Line Blocking HTTP layer (pipelining) Only TCP layer
TLS Requirement Optional De facto required (browsers only support over TLS)
Page Load Time Baseline 10-30% faster

Why HTTP/2 Was Needed

HTTP/1.1 problems that HTTP/2 solves:

  • Head-of-line blocking: HTTP/1.1 pipelining failed. HTTP/2 multiplexing succeeds.
  • Connection overhead: Opening 6 TCP connections per domain = 6 handshakes (6 RTT). HTTP/2 uses 1 connection.
  • Header overhead: Repetitive headers on every request. HPACK reduces bandwidth by 80-95%.
  • Resource loading: Modern pages load 100+ resources. HTTP/1.1 serializes them (even with 6 connections). HTTP/2 parallelizes on 1 connection.

Real numbers: Page with 100 resources, 50ms RTT:

  • HTTP/1.1: ~17 rounds (100 resources Γ· 6 connections) Γ— 50ms = ~850ms
  • HTTP/2: ~1 round (all multiplexed) Γ— 50ms = ~50ms (17x faster)
Key Takeaway

HTTP/2 eliminates HTTP-layer head-of-line blocking via multiplexing, but TCP-layer HOL blocking remains. If a TCP packet is lost, all streams on that connection stall. HTTP/3 solves this by moving to QUIC (UDP-based).

Interview Signal

Strong candidates explain that HTTP/2 multiplexing only solves HTTP-layer HOL blocking, not TCP-layer. On lossy networks (1% packet loss), HTTP/2 can be slower than HTTP/1.1 with 6 connections because 1 lost packet blocks all streams. This is why HTTP/3 was created despite HTTP/2 being recent.

1.8 HTTP/3 & QUIC

What is HTTP/3?

HTTP/3 (RFC 9114, 2022) is the latest version of HTTP, built on QUIC instead of TCP. It solves HTTP/2's remaining problem: TCP head-of-line blocking.

Adoption: ~30% of websites (Google, Facebook, Cloudflare, Shopify). Supported by Chrome, Firefox, Edge, Safari.

Why HTTP/3? The TCP Problem

HTTP/2 multiplexes streams over a single TCP connection. If one TCP packet is lost, the entire connection stalls (all streams) until the packet is retransmitted. This is TCP head-of-line blocking.

sequenceDiagram participant Browser participant Network participant Server Note over Browser,Server: HTTP/2 over TCP Browser->>Network: Stream 1 packet 1 Browser->>Network: Stream 2 packet 1 Browser->>Network: Stream 1 packet 2 (lost!) Browser->>Network: Stream 3 packet 1 Network->>Server: Stream 1 packet 1 Network->>Server: Stream 2 packet 1 Network->>Server: Stream 3 packet 1 Note over Server: Cannot process any stream
until Stream 1 packet 2 arrives
(TCP guarantees in-order delivery) Browser->>Network: Retransmit Stream 1 packet 2 Network->>Server: Stream 1 packet 2 Note over Server: Now all streams unblocked

Impact: On networks with 1% packet loss, HTTP/2 throughput drops 20-50% compared to HTTP/1.1 with multiple connections.

QUIC Architecture

QUIC (Quick UDP Internet Connections) is a transport protocol built on UDP. It reimplements TCP's reliability, congestion control, and flow control in userspace, while adding stream multiplexing and built-in encryption.

graph TD subgraph "HTTP/2 Stack" H2_App[HTTP/2] H2_TLS[TLS 1.3] H2_TCP[TCP] H2_IP[IP] end subgraph "HTTP/3 Stack" H3_App[HTTP/3] H3_QUIC[QUIC
includes TLS 1.3] H3_UDP[UDP] H3_IP[IP] end H2_App --> H2_TLS H2_TLS --> H2_TCP H2_TCP --> H2_IP H3_App --> H3_QUIC H3_QUIC --> H3_UDP H3_UDP --> H3_IP style H2_TCP fill:#ff6b6b,color:#1a1a2e style H3_QUIC fill:#4ecdc4,color:#1a1a2e style H3_UDP fill:#95e1d3,color:#1a1a2e

Key insight: QUIC moves reliability and encryption from kernel (TCP + TLS) to userspace (QUIC library). This enables faster iteration and per-stream ordering.

0-RTT Connection Establishment

HTTP/2 over TCP + TLS 1.3 requires 2 RTT minimum (1 for TCP, 1 for TLS). QUIC supports 0-RTT resumption for previously seen servers.

sequenceDiagram participant Client participant Server Note over Client,Server: First Connection (1-RTT) Client->>Server: QUIC Initial + TLS ClientHello Server-->>Client: QUIC Handshake + TLS ServerHello + Encrypted Data Note over Client: Server sends config, session ticket Note over Client,Server: Time passes (hours/days) Note over Client,Server: Resumed Connection (0-RTT) Client->>Server: QUIC 0-RTT + Encrypted HTTP Request
(using cached session ticket) Server-->>Client: Encrypted HTTP Response Note over Client,Server: Data sent immediately!
No round trips before request rect rgb(255, 200, 200) Note over Client,Server: Compare: TCP + TLS 1.3 (2-RTT minimum) Client->>Server: TCP SYN Server-->>Client: TCP SYN-ACK Client->>Server: TCP ACK + TLS ClientHello Server-->>Client: TLS ServerHello Client->>Server: HTTP Request Server-->>Client: HTTP Response end

Latency savings:

  • US-Europe (100ms RTT): 200ms saved per request
  • Mobile (200ms RTT): 400ms saved per request

Security note: 0-RTT data is not forward-secure and vulnerable to replay attacks. Only safe for idempotent requests (GET, not POST).

Independent Stream Multiplexing (No HOL Blocking)

QUIC provides per-stream ordering, not global ordering. Lost packet in stream 1 only blocks stream 1, not streams 2, 3, 4.

sequenceDiagram participant Client participant Network participant Server Note over Client,Server: HTTP/3 over QUIC Client->>Network: Stream 1 packet 1 Client->>Network: Stream 2 packet 1 Client->>Network: Stream 1 packet 2 (lost!) Client->>Network: Stream 3 packet 1 Network->>Server: Stream 1 packet 1 Network->>Server: Stream 2 packet 1 Network->>Server: Stream 3 packet 1 Note over Server: Process Stream 2 and 3 immediately
Only Stream 1 waits for retransmission Server-->>Client: Stream 2 response Server-->>Client: Stream 3 response Client->>Network: Retransmit Stream 1 packet 2 Network->>Server: Stream 1 packet 2 Server-->>Client: Stream 1 response

Performance impact: On 1% lossy network, HTTP/3 is 30-50% faster than HTTP/2.

Connection Migration

TCP connections are identified by 4-tuple (source IP, source port, dest IP, dest port). Changing networks (WiFi β†’ cellular) breaks the connection.

QUIC connections are identified by a Connection ID (independent of IP/port). Connection survives network changes.

sequenceDiagram participant Phone participant WiFi as WiFi Network 192.168.1.10 participant Cellular as Cellular Network 10.20.30.40 participant Server Note over Phone: Connected via WiFi Phone->>WiFi: QUIC packet (conn_id=abc123, src=192.168.1.10) WiFi->>Server: QUIC packet Server-->>WiFi: Response WiFi-->>Phone: Response Note over Phone: WiFi signal lost
Switch to cellular Phone->>Cellular: QUIC packet (conn_id=abc123, src=10.20.30.40) Cellular->>Server: QUIC packet Note over Server: Same conn_id!
Connection continues seamlessly Server-->>Cellular: Response Cellular-->>Phone: Response Note over Phone,Server: No reconnection, no handshake
Download continues without interruption

Use case: Mobile apps downloading large files. User walks out of WiFi range, switches to cellular. Download continues without restarting.

HTTP/2 vs HTTP/3 Comparison

Feature HTTP/2 HTTP/3
Transport Protocol TCP QUIC (over UDP)
Connection Setup 2-3 RTT (TCP + TLS) 1 RTT (first connection), 0 RTT (resumed)
Head-of-Line Blocking TCP layer (all streams blocked) None (per-stream ordering)
Connection Migration No (IP:port change = new connection) Yes (connection ID survives network change)
Encryption TLS 1.2 or 1.3 (separate layer) TLS 1.3 integrated (all packets encrypted)
Congestion Control TCP kernel (slow to update) QUIC userspace (fast iteration)
Packet Loss (1%) 20-50% throughput drop Minimal impact
Adoption ~50% of sites ~30% of sites (growing)

Why HTTP/3 Exists Despite HTTP/2 Being Recent

HTTP/2 was standardized in 2015. Why replace it 7 years later?

  1. TCP HOL blocking is unfixable: TCP is a kernel protocol with in-order delivery baked in. Can't change without breaking the internet.
  2. Mobile networks are lossy: 1-2% packet loss is common on cellular. HTTP/2 performance degrades badly on lossy networks.
  3. TLS handshake is slow: 1-2 RTT adds 50-400ms on every connection. 0-RTT is a game-changer for mobile.
  4. Connection migration needed: Users switch networks constantly (WiFi ↔ cellular). TCP can't handle it.
  5. Innovation velocity: TCP is in the kernel, updated every ~5 years. QUIC is userspace, updated every ~6 months.

Google's motivation: YouTube and Search make millions of requests/second. Saving 1 RTT per request = billions of RTT saved = faster load times = more engagement.

Key Takeaway

HTTP/3 trades TCP's ubiquity for QUIC's performance. On clean networks, HTTP/2 and HTTP/3 are similar. On lossy networks (mobile, congested WiFi), HTTP/3 is 30-50% faster. The 0-RTT handshake alone saves 100-400ms on mobile.

Interview Signal

Candidates who mention "HTTP/3 uses UDP" without explaining why are surface-level. Strong answers: "HTTP/3 uses QUIC over UDP to eliminate TCP head-of-line blocking. Lost packet in stream 1 doesn't block stream 2. This matters on mobile networks with 1-2% loss. Also, 0-RTT connection resumption saves 100-400ms per request on mobile."

1.9 TLS/SSL (Transport Layer Security)

What is TLS?

TLS (Transport Layer Security) encrypts data between client and server, providing confidentiality, integrity, and authentication. It sits between the application layer (HTTP) and transport layer (TCP).

SSL (Secure Sockets Layer) is the deprecated predecessor. SSL 3.0 was replaced by TLS 1.0 in 1999. Today "SSL" colloquially refers to TLS.

TLS Versions

  • TLS 1.0 (1999): Deprecated (insecure)
  • TLS 1.1 (2006): Deprecated (insecure)
  • TLS 1.2 (2008): Widely used (74% of connections in 2024), secure if configured properly
  • TLS 1.3 (2018): Modern standard (26% of connections, growing), faster and more secure

TLS 1.2 Handshake (2-RTT)

TLS 1.2 requires 2 round trips to establish a secure connection (after TCP handshake):

sequenceDiagram participant Client participant Server Note over Client,Server: TCP 3-way handshake (1 RTT) Client->>Server: TCP SYN Server-->>Client: TCP SYN-ACK Client->>Server: TCP ACK Note over Client,Server: TLS 1.2 Handshake (2 RTT) rect rgb(255, 230, 230) Note over Client,Server: RTT 1 Client->>Server: ClientHello
(supported cipher suites, random nonce) Server-->>Client: ServerHello
(chosen cipher, random nonce)
+ Certificate
(server's public key + CA signature)
+ ServerHelloDone end rect rgb(230, 255, 230) Note over Client,Server: RTT 2 Client->>Server: ClientKeyExchange
(pre-master secret, encrypted with server's public key)
+ ChangeCipherSpec
+ Finished Note over Client: Derive session keys
from pre-master + nonces Note over Server: Decrypt pre-master secret
Derive same session keys Server-->>Client: ChangeCipherSpec + Finished end Note over Client,Server: Secure channel established
Total: 3 RTT (TCP + TLS) Client->>Server: HTTP Request (encrypted) Server-->>Client: HTTP Response (encrypted)

Key steps:

  1. ClientHello: Client announces supported TLS versions, cipher suites, compression methods
  2. ServerHello: Server picks TLS version and cipher suite, sends certificate
  3. Certificate validation: Client verifies server's certificate against trusted CAs
  4. Key exchange: Client generates pre-master secret, encrypts with server's public key
  5. Session keys: Both derive symmetric encryption keys from pre-master + random nonces
  6. Finished: Both send encrypted "Finished" messages to confirm handshake

Total latency: 3 RTT (1 TCP + 2 TLS) = 150-600ms for intercontinental connections

TLS 1.3 Handshake (1-RTT)

TLS 1.3 reduces handshake to 1 RTT by combining key exchange with ClientHello:

sequenceDiagram participant Client participant Server Note over Client,Server: TCP 3-way handshake (1 RTT) Client->>Server: TCP SYN Server-->>Client: TCP SYN-ACK Client->>Server: TCP ACK Note over Client,Server: TLS 1.3 Handshake (1 RTT) rect rgb(255, 230, 230) Client->>Server: ClientHello
+ KeyShare (DH public key)
+ SupportedGroups
+ SignatureAlgorithms Note over Client: Speculatively send
key exchange parameters Server-->>Client: ServerHello
+ KeyShare (DH public key)
+ Certificate
+ CertificateVerify
+ Finished Note over Server: Derive session keys
from DH key exchange end Client->>Server: Finished Note over Client: Derive session keys Note over Client,Server: Secure channel established
Total: 2 RTT (TCP + TLS) Client->>Server: HTTP Request (encrypted) Server-->>Client: HTTP Response (encrypted)

Key improvements:

  • 1-RTT handshake: Client speculatively sends key share in first message
  • Fewer cipher suites: Removed weak algorithms (RC4, MD5, SHA-1, RSA key exchange)
  • Forward secrecy mandatory: Ephemeral Diffie-Hellman (DHE/ECDHE) required
  • Encrypted handshake: More of the handshake is encrypted (hides server certificate from eavesdroppers)
  • 0-RTT resumption: For repeated connections, send encrypted data in first packet (like QUIC)

Latency savings: 50-200ms per connection (1 RTT saved)

Certificate Chain Validation

TLS uses a chain of trust from website certificate β†’ intermediate CA β†’ root CA. Client trusts the root CA (pre-installed in OS/browser).

graph TD Root[Root CA
DigiCert Global Root] Intermediate[Intermediate CA
DigiCert SHA2 Secure Server CA] Leaf[Website Certificate
*.example.com] Browser[Browser
Trusts Root CA] Root -->|Signs| Intermediate Intermediate -->|Signs| Leaf Browser -.->|Pre-installed trust| Root Leaf -->|1. Verify signature| Intermediate Intermediate -->|2. Verify signature| Root Root -->|3. Trusted?| Browser style Root fill:#ff6b6b,color:#1a1a2e style Intermediate fill:#4ecdc4,color:#1a1a2e style Leaf fill:#95e1d3,color:#1a1a2e style Browser fill:#ffd93d,color:#1a1a2e

Validation steps:

  1. Client receives server certificate (leaf) and intermediate CA certificate
  2. Verify leaf certificate signature using intermediate CA's public key
  3. Verify intermediate CA certificate signature using root CA's public key
  4. Check root CA is in trusted store (browser/OS)
  5. Verify certificate is not expired and domain matches
  6. Check Certificate Revocation List (CRL) or OCSP (Online Certificate Status Protocol)

Public Key Infrastructure (PKI)

Certificate Authorities (CAs) are trusted organizations that issue certificates. Browsers/OS ship with ~100-200 trusted root CAs.

Major CAs: DigiCert, Let's Encrypt, GlobalSign, Sectigo

Let's Encrypt: Free, automated CA. Issues 300M+ certificates. Uses ACME protocol (Automatic Certificate Management Environment) for domain validation.

Cipher Suites Explained

A cipher suite defines algorithms for key exchange, authentication, encryption, and MAC (Message Authentication Code).

Example (TLS 1.2): TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

  • ECDHE: Elliptic Curve Diffie-Hellman Ephemeral (key exchange, forward secrecy)
  • RSA: RSA signature (authentication)
  • AES_128_GCM: AES encryption in Galois/Counter Mode (128-bit key, authenticated encryption)
  • SHA256: Hash function for HMAC

Example (TLS 1.3): TLS_AES_256_GCM_SHA384 (simplified, key exchange implicit)

Perfect Forward Secrecy (PFS)

Perfect Forward Secrecy ensures that if the server's private key is compromised, past sessions remain secure. Achieved by using ephemeral keys (generated per session).

How it works (Diffie-Hellman):

  1. Client and server generate temporary key pairs (discarded after session)
  2. Exchange public keys
  3. Both compute shared secret using their private key + other's public key
  4. Derive session keys from shared secret
  5. Discard temporary private keys after session ends

Without PFS: Attacker records encrypted traffic, steals server's private key years later, decrypts all past sessions.

With PFS: Server's private key only used for authentication (signing), not encryption. Past sessions remain secure.

Certificate Pinning

Certificate pinning hardcodes expected certificate or public key in the application. Prevents man-in-the-middle attacks using rogue CAs.

Use case: Mobile apps connecting to specific API. Pin the expected certificate fingerprint.

Risk: If certificate expires or rotates, app breaks. Must be updated.

Alternative: HTTP Public Key Pinning (HPKP, deprecated) or Certificate Transparency logs.

Mutual TLS (mTLS)

Standard TLS: client verifies server's certificate. Mutual TLS: server also verifies client's certificate.

sequenceDiagram participant Client participant Server Note over Client,Server: Standard TLS Client->>Server: ClientHello Server-->>Client: ServerHello + Certificate Note over Client: Verify server certificate Client->>Server: Key exchange Note over Client,Server: Server authenticated
Client not authenticated Note over Client,Server: Mutual TLS (mTLS) Client->>Server: ClientHello Server-->>Client: ServerHello + Certificate
+ CertificateRequest Note over Client: Verify server certificate Client->>Server: Certificate + Key exchange Note over Server: Verify client certificate Note over Client,Server: Both authenticated

Use case:

  • Service-to-service communication: Microservices authenticate each other (zero-trust architecture)
  • API authentication: Client certificate instead of API keys
  • Enterprise VPNs: User certificate for authentication

Adoption: Common in service meshes (Istio, Linkerd, Consul Connect).

TLS 1.2 vs TLS 1.3 Comparison

Feature TLS 1.2 TLS 1.3
Handshake RTT 2 RTT 1 RTT (0-RTT resumption)
Cipher Suites 37 options (many weak) 5 options (all strong)
Forward Secrecy Optional (DHE/ECDHE) Mandatory (always ephemeral keys)
RSA Key Exchange Supported Removed (no PFS)
Handshake Encryption Minimal (most plaintext) Extensive (certificate encrypted)
Weak Algorithms RC4, 3DES, MD5, SHA-1 allowed All removed
Session Resumption Session IDs or tickets PSK (Pre-Shared Key) mode
Latency (intercontinental) 200-400ms 100-200ms (1 RTT saved)
Key Takeaway

TLS 1.3 is faster and more secure. The 1-RTT handshake saves 100-200ms per connection. Removing weak cipher suites eliminates configuration mistakes. Forward secrecy is mandatory, protecting past sessions if server is compromised. Adopt TLS 1.3 unless supporting legacy clients (IE 10, Android 4.x).

Interview Signal

Weak answers: "TLS encrypts traffic." Strong answers: "TLS provides confidentiality (encryption), integrity (MAC), and authentication (certificates). TLS 1.3 reduces handshake from 2 RTT to 1 RTT, saving 100-200ms. Perfect forward secrecy (ephemeral keys) ensures past sessions remain secure even if server key is compromised. This is why TLS 1.3 mandates ECDHE."

1.10 WebSockets

What are WebSockets?

WebSockets (RFC 6455, 2011) provide full-duplex, bidirectional communication over a single TCP connection. Unlike HTTP's request-response model, WebSockets allow server and client to send messages independently at any time.

Use cases: Real-time chat, live notifications, multiplayer games, collaborative editing, live dashboards, stock tickers

HTTP Upgrade Handshake

WebSockets start as HTTP, then upgrade to the WebSocket protocol using the Upgrade header:

sequenceDiagram participant Browser participant Server Note over Browser,Server: TCP + TLS handshake (2-3 RTT) Browser->>Server: TCP + TLS connection established Note over Browser,Server: HTTP Upgrade Handshake rect rgb(255, 230, 230) Browser->>Server: HTTP Request
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZQ==
Sec-WebSocket-Version: 13 end rect rgb(230, 255, 230) Server-->>Browser: HTTP Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= end Note over Browser,Server: Protocol switched to WebSocket
Full-duplex communication begins Browser->>Server: WebSocket frame: "Hello" Server-->>Browser: WebSocket frame: "Hi there!" Server->>Browser: WebSocket frame: "New message" Browser->>Server: WebSocket frame: "Got it" Note over Browser,Server: Both sides can send anytime
No request-response pattern

Key headers:

  • Upgrade: websocket - Request protocol upgrade
  • Connection: Upgrade - Connection should be upgraded
  • Sec-WebSocket-Key - Random base64 value (prevents caching proxies from reusing connection)
  • Sec-WebSocket-Accept - SHA-1 hash of key + magic string (proves server understands WebSocket)

Full-Duplex Communication

Unlike HTTP (client initiates, server responds), WebSockets are full-duplex: both sides can send messages independently.

graph LR subgraph "HTTP (Half-Duplex)" H_Client[Client] -->|Request| H_Server[Server] H_Server -->|Response| H_Client H_Client -->|New Request| H_Server H_Server -->|New Response| H_Client end subgraph "WebSocket (Full-Duplex)" WS_Client[Client] WS_Server[Server] WS_Client <-->|Simultaneous
bidirectional messages| WS_Server end style H_Client fill:#ffd93d,color:#1a1a2e style H_Server fill:#ff6b6b,color:#1a1a2e style WS_Client fill:#95e1d3,color:#1a1a2e style WS_Server fill:#4ecdc4,color:#1a1a2e

Benefit: Server can push data without client polling. Eliminates latency of request-response cycle.

WebSocket Frame Format

After the upgrade, all data is sent as frames (binary protocol, not text like HTTP):

WebSocket Frame Structure:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   FIN   β”‚  RSV1-3 β”‚ Opcode  β”‚   Mask      β”‚   Payload   β”‚   Payload    β”‚
β”‚  (1 bit)β”‚ (3 bits)β”‚ (4 bits)β”‚   (1 bit)   β”‚  Length     β”‚    Data      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Opcode values:
0x0 - Continuation frame (multi-frame message)
0x1 - Text frame (UTF-8)
0x2 - Binary frame
0x8 - Close connection
0x9 - Ping (heartbeat)
0xA - Pong (heartbeat response)

Masking:
- Client β†’ Server: Always masked (XOR with random key)
- Server β†’ Client: Never masked
- Prevents proxy cache poisoning attacks

Why masking? Prevents malicious JS from crafting frames that look like HTTP requests to trick caching proxies.

When to Use WebSockets

Use WebSockets when:

  • Real-time bidirectional communication: Chat apps, multiplayer games, collaborative editing (Google Docs)
  • High-frequency updates: Live sports scores, stock tickers, monitoring dashboards
  • Low latency critical: Gaming (10-50ms updates), financial trading, remote desktop
  • Server-initiated messages: Notifications, alerts, live updates

When not to use WebSockets:

  • Simple request-response: Standard HTTP is simpler and better supported
  • Infrequent updates: Polling or SSE is sufficient (don't maintain persistent connection)
  • Large file uploads: HTTP handles resumption better
  • RESTful APIs: HTTP is the standard (cacheable, stateless)

WebSocket vs Alternatives

Feature WebSocket SSE Long Polling HTTP/2 Streams
Direction Bidirectional Server β†’ Client only Client β†’ Server (polling) Bidirectional
Protocol WebSocket (upgraded HTTP) HTTP (text/event-stream) HTTP HTTP/2
Connection Persistent (1 TCP) Persistent (1 TCP) Short-lived (many TCP) Persistent (1 TCP)
Overhead Low (2-byte frames) Medium (HTTP headers per message) High (full HTTP per poll) Low (binary frames)
Browser Support Universal (IE 10+) Universal (IE/Edge via polyfill) Universal Universal (IE 11+)
Firewall/Proxy Can be blocked Works everywhere (HTTP) Works everywhere Works everywhere
Reconnection Manual Automatic (EventSource) Manual Manual
Latency 1-10ms 1-10ms 100-1000ms+ (poll interval) 1-10ms
Use Case Chat, gaming, collaborative Notifications, feeds, logs Legacy browser support Modern apps (gRPC)
Key Takeaway

WebSockets are for real-time bidirectional communication. Use when server needs to push updates frequently (>1/sec) or client and server exchange messages back and forth (chat, gaming). For server-to-client only (notifications, stock tickers), SSE is simpler. For rare updates (<1/min), polling is fine.

Interview Signal

Weak answers: "WebSockets are for real-time." Strong answers: "WebSockets provide full-duplex communication over a single persistent TCP connection. They start with HTTP upgrade (101 Switching Protocols) then use binary framing. Best for bidirectional real-time (chat, gaming). For server-to-client only, SSE is simpler. Downsides: stateful (harder to scale), can be blocked by proxies, no HTTP caching."

1.11 Server-Sent Events (SSE)

What is SSE?

Server-Sent Events (SSE) is a standard for one-way streaming from server to client over HTTP. The server holds the connection open and sends events as they occur.

Use cases: Live notifications, news feeds, stock tickers, server logs, progress updates, social media feeds

How SSE Works

SSE uses standard HTTP with Content-Type: text/event-stream. Server keeps connection open and sends events in text format:

sequenceDiagram participant Browser participant Server Note over Browser: JavaScript: new EventSource('/events') Browser->>Server: GET /events HTTP/1.1
Accept: text/event-stream Server-->>Browser: HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive Note over Server,Browser: Connection held open Server->>Browser: data: First event

Note over Browser: Fires 'message' event Server->>Browser: event: user-joined
data: {"name":"Alice"}
id: 1

Note over Browser: Fires 'user-joined' event Server->>Browser: data: Another event
id: 2

Note over Browser: Connection drops
(network issue) Browser->>Server: GET /events HTTP/1.1
Last-Event-ID: 2 Note over Server: Resume from event 2 Server-->>Browser: data: Resumed event
id: 3

Event Format

Events are text-based, newline-delimited:

Simple event:
data: This is a simple message

Multi-line event:
data: First line
data: Second line
data: Third line

Named event with ID:
event: userJoined
data: {"userId": 123, "name": "Alice"}
id: 1

Comment (ignored by client):
: This is a comment

Retry interval (milliseconds):
retry: 10000

Fields:

  • data - Event payload (text or JSON)
  • event - Event type (default: "message")
  • id - Event ID for reconnection
  • retry - Reconnection delay in milliseconds

EventSource API (Browser)

JavaScript code:

// Create connection
const eventSource = new EventSource('/events');

// Listen for messages (default event type)
eventSource.onmessage = (event) => {
  console.log('New message:', event.data);
};

// Listen for custom event types
eventSource.addEventListener('userJoined', (event) => {
  const user = JSON.parse(event.data);
  console.log('User joined:', user.name);
});

// Handle errors
eventSource.onerror = (error) => {
  console.error('SSE error:', error);
  // EventSource auto-reconnects
};

// Close connection
eventSource.close();

Automatic Reconnection with Last-Event-ID

If the connection drops, EventSource automatically reconnects and sends the Last-Event-ID header. Server can resume from that point.

sequenceDiagram participant Browser as Browser (EventSource) participant Server Note over Browser,Server: Initial connection Browser->>Server: GET /events Server-->>Browser: data: Event 1
id: 1

Server-->>Browser: data: Event 2
id: 2

Server-->>Browser: data: Event 3
id: 3

Note over Browser,Server: Connection lost (timeout, network issue) Note over Browser: Wait retry interval (default: 3s) Browser->>Server: GET /events
Last-Event-ID: 3 Note over Server: Server sees last received event
Can skip already-sent events Server-->>Browser: data: Event 4
id: 4

Server-->>Browser: data: Event 5
id: 5

Note over Browser,Server: Connection resumed seamlessly

Server-side implementation:

// Node.js + Express example
app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const lastEventId = req.headers['last-event-id'];
  // Resume from lastEventId if provided

  let eventId = parseInt(lastEventId || '0');

  const sendEvent = (data) => {
    eventId++;
    res.write(`id: ${eventId}\n`);
    res.write(`data: ${JSON.stringify(data)}\n\n`);
  };

  // Send event every 5 seconds
  const interval = setInterval(() => {
    sendEvent({ message: 'Hello', timestamp: Date.now() });
  }, 5000);

  // Clean up on disconnect
  req.on('close', () => {
    clearInterval(interval);
  });
});

When to Prefer SSE Over WebSockets

Use SSE when:

  • Server-to-client only: Notifications, feeds, logs, monitoring (no need for client-to-server messages)
  • Simplicity: SSE is standard HTTP (easier debugging, caching, proxies)
  • Automatic reconnection: Built into EventSource (WebSockets require manual reconnection logic)
  • HTTP/2 multiplexing: Multiple SSE streams share one connection (no 6-connection limit)
  • Progressive enhancement: Falls back gracefully (polyfills for old browsers)

SSE limitations:

  • Unidirectional: Server β†’ Client only (client must use separate HTTP requests to send data)
  • Text only: Data must be UTF-8 text (JSON, XML, plain text). Binary requires base64 encoding.
  • Browser connection limit: 6 SSE connections per domain (HTTP/1.1). Use HTTP/2 for multiplexing.

SSE Sequence Diagram

sequenceDiagram participant User participant Browser participant Server participant Database User->>Browser: Open stock ticker page Browser->>Server: GET /stock-prices (EventSource) Server-->>Browser: 200 OK (text/event-stream)
Connection held open loop Every second Database->>Server: New price data Server->>Browser: data: {"symbol":"AAPL","price":175.23}
id: 123

Browser->>User: Update UI (stock price) end Note over Browser: User switches tab
(browser may throttle) Note over Server,Browser: 5 minutes idle Server->>Browser: : keepalive comment

Note over Server: Prevent timeout/proxy closing connection Note over Browser: Network disconnects Browser->>Server: GET /stock-prices
Last-Event-ID: 123 Server-->>Browser: Resume from event 123
Key Takeaway

SSE is the simplest way to stream server-to-client. Use for live feeds, notifications, logs. Built-in reconnection with Last-Event-ID eliminates boilerplate. For bidirectional communication (chat, gaming), use WebSockets instead. SSE is just HTTP, so it works through proxies, supports HTTP/2 multiplexing, and is easier to debug.

Interview Signal

Strong candidates compare SSE vs WebSockets: "SSE is server-to-client streaming over HTTP (text/event-stream). Simpler than WebSockets (standard HTTP, automatic reconnection with Last-Event-ID). Best for notifications, feeds, logs. Limitations: unidirectional (client must use separate requests to send data) and text-only. For bidirectional real-time, use WebSockets."

1.12 gRPC

What is gRPC?

gRPC (gRPC Remote Procedure Call) is a high-performance, open-source RPC framework developed by Google. It uses HTTP/2 for transport, Protocol Buffers for serialization, and supports 4 types of streaming.

Use cases: Microservices communication, mobile backends, real-time services, IoT, APIs with strict performance requirements

gRPC Architecture

graph TB subgraph "Client Application" ClientCode[Application Code] ClientStub[gRPC Stub
generated code] end subgraph "gRPC Stack" HTTP2[HTTP/2 Transport] Protobuf[Protocol Buffers
Serialization] end subgraph "Server Application" ServerCode[Service Implementation] ServerStub[gRPC Server
generated code] end ClientCode -->|Method call| ClientStub ClientStub -->|Serialize| Protobuf Protobuf -->|Binary frames| HTTP2 HTTP2 -->|Network| HTTP2 HTTP2 -->|Binary frames| Protobuf Protobuf -->|Deserialize| ServerStub ServerStub -->|Invoke| ServerCode style HTTP2 fill:#4ecdc4,color:#1a1a2e style Protobuf fill:#95e1d3,color:#1a1a2e style ClientStub fill:#ffd93d,color:#1a1a2e style ServerStub fill:#ffd93d,color:#1a1a2e

Key components:

  • Protocol Buffers (protobuf): Binary serialization format (smaller and faster than JSON)
  • HTTP/2: Multiplexing, streaming, header compression
  • Code generation: Client stubs and server skeletons generated from .proto files
  • Service definitions: Strongly typed contracts (like WSDL for SOAP)

Protocol Buffers (Protobuf)

Protobuf is a language-neutral, platform-neutral binary serialization format. It's 3-10x smaller and 20-100x faster than JSON.

Example .proto file:

syntax = "proto3";

package ecommerce;

service ProductService {
  rpc GetProduct (ProductRequest) returns (ProductResponse);
  rpc ListProducts (ListProductsRequest) returns (stream ProductResponse);
  rpc CreateProduct (stream ProductRequest) returns (ProductSummary);
  rpc UpdateProducts (stream ProductRequest) returns (stream ProductResponse);
}

message ProductRequest {
  int32 product_id = 1;
}

message ProductResponse {
  int32 product_id = 1;
  string name = 2;
  double price = 3;
  repeated string tags = 4;
}

message ListProductsRequest {
  int32 page_size = 1;
  string page_token = 2;
}

message ProductSummary {
  int32 total_created = 1;
}

Code generation:

# Generate Go code
protoc --go_out=. --go-grpc_out=. product.proto

# Generate Python code
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. product.proto

# Generate Java code
protoc --java_out=. --grpc-java_out=. product.proto

Protobuf vs JSON:

Feature JSON Protobuf
Encoding Text (UTF-8) Binary
Size Baseline (100%) 30-50% smaller
Speed Baseline 20-100x faster
Schema No schema (runtime validation) Strict schema (.proto file)
Readability Human-readable Binary (not readable)
Versioning Manual (breaking changes risky) Built-in (field numbers, optional)
Browser Support Native Requires library + gRPC-Web

Four Streaming Modes

gRPC supports four communication patterns:

1. Unary RPC (Request-Response)

Standard request-response, like REST:

sequenceDiagram participant Client participant Server Client->>Server: GetProduct(id=123) Server-->>Client: ProductResponse(name="Laptop", price=999.99)
rpc GetProduct (ProductRequest) returns (ProductResponse);

2. Server Streaming

Client sends one request, server sends stream of responses:

sequenceDiagram participant Client participant Server Client->>Server: ListProducts(page_size=10) Server-->>Client: ProductResponse (id=1, name="Laptop") Server-->>Client: ProductResponse (id=2, name="Phone") Server-->>Client: ProductResponse (id=3, name="Tablet") Note over Server: ...more products Server-->>Client: ProductResponse (id=10, name="Monitor") Note over Server: Stream complete
rpc ListProducts (ListProductsRequest) returns (stream ProductResponse);

Use case: Large result sets, live updates, log streaming

3. Client Streaming

Client sends stream of requests, server sends one response:

sequenceDiagram participant Client participant Server Client->>Server: CreateProduct (product 1) Client->>Server: CreateProduct (product 2) Client->>Server: CreateProduct (product 3) Note over Client: ...more products Client->>Server: Stream complete Server-->>Client: ProductSummary (total_created=100)
rpc CreateProduct (stream ProductRequest) returns (ProductSummary);

Use case: Batch uploads, telemetry, file uploads

4. Bidirectional Streaming

Both client and server send streams independently:

sequenceDiagram participant Client participant Server Client->>Server: UpdateProducts (product 1) Server-->>Client: ProductResponse (updated product 1) Client->>Server: UpdateProducts (product 2) Client->>Server: UpdateProducts (product 3) Server-->>Client: ProductResponse (updated product 2) Server-->>Client: ProductResponse (updated product 3) Note over Client,Server: Both send/receive independently Client->>Server: Stream complete Server-->>Client: Stream complete
rpc UpdateProducts (stream ProductRequest) returns (stream ProductResponse);

Use case: Chat applications, real-time collaboration, game servers

gRPC vs REST vs GraphQL

Feature REST gRPC GraphQL
Protocol HTTP/1.1, HTTP/2 HTTP/2 (required) HTTP/1.1, HTTP/2
Serialization JSON, XML Protocol Buffers (binary) JSON
Schema Optional (OpenAPI/Swagger) Required (.proto files) Required (GraphQL schema)
Payload Size Baseline (JSON) 30-50% smaller Similar to JSON (or larger)
Speed Baseline 5-10x faster (binary, HTTP/2) Similar to REST (or slower)
Streaming Chunked encoding (limited) 4 modes (unary, server, client, bidirectional) Subscriptions (WebSocket)
Browser Support Native Via gRPC-Web (proxy required) Native
Caching HTTP caching (GET requests) No (POST-based) No (POST-based)
Code Generation Optional Automatic (from .proto) Optional
Human Readability High (JSON/XML) Low (binary) High (JSON)
Tooling curl, Postman, browsers grpcurl, BloomRPC, specialized GraphiQL, Playground
Best For Public APIs, CRUD, web apps Microservices, high-performance, streaming Flexible queries, mobile apps, aggregation

When to Use gRPC

Use gRPC when:

  • Microservices: Internal service-to-service communication (high throughput, low latency)
  • Real-time streaming: Live data feeds, bidirectional communication
  • Polyglot systems: Services in different languages (protobuf supports 10+ languages)
  • Mobile backends: Bandwidth-constrained, battery-sensitive (smaller payloads)
  • Performance critical: Trading systems, gaming, IoT (5-10x faster than JSON)

Don't use gRPC for:

  • Public APIs: REST is standard, more accessible (curl, Postman, browsers)
  • Browser clients: Requires gRPC-Web + proxy (Envoy). WebSockets simpler for bidirectional.
  • Simple CRUD: REST is simpler, more tooling, HTTP caching
  • Human debugging: Binary format not readable (use logging, monitoring)

Service Definition Example

Complete example with all 4 streaming modes:

syntax = "proto3";

package chat;

service ChatService {
  // Unary: Login
  rpc Login (LoginRequest) returns (LoginResponse);

  // Server streaming: Receive messages
  rpc StreamMessages (StreamRequest) returns (stream Message);

  // Client streaming: Send multiple messages
  rpc SendMessages (stream Message) returns (SendSummary);

  // Bidirectional streaming: Live chat
  rpc Chat (stream Message) returns (stream Message);
}

message LoginRequest {
  string username = 1;
  string password = 2;
}

message LoginResponse {
  string token = 1;
  string user_id = 2;
}

message StreamRequest {
  string user_id = 1;
  int64 since_timestamp = 2;
}

message Message {
  string message_id = 1;
  string user_id = 2;
  string content = 3;
  int64 timestamp = 4;
}

message SendSummary {
  int32 messages_sent = 1;
}
Key Takeaway

gRPC is for high-performance service-to-service communication. Protocol Buffers are 3-10x smaller and 20-100x faster than JSON. HTTP/2 multiplexing + streaming makes it ideal for microservices. Use for internal APIs, not public (REST is more accessible). For browsers, consider REST or GraphQL unless performance is critical (then use gRPC-Web).

Interview Signal

Strong candidates explain the trade-offs: "gRPC uses HTTP/2 + Protobuf for 5-10x faster serialization and smaller payloads (30-50% vs JSON). Best for microservices (internal, high throughput). Four streaming modes: unary (REST-like), server streaming (large results), client streaming (uploads), bidirectional (chat). Downsides: binary format (hard to debug), requires HTTP/2, poor browser support (needs gRPC-Web proxy). Use REST for public APIs."