Networking & Protocols#

Understanding how data moves across the network is the foundation of system design. Every architectural decision — from API style to database placement — is constrained by networking realities.

DNS Resolution#

The Domain Name System translates human-readable domain names into IP addresses. A single page load may trigger dozens of DNS lookups.

Resolution Flow#

sequenceDiagram
    participant Client
    participant Resolver as Recursive Resolver
    participant Root as Root NS
    participant TLD as TLD NS (.com)
    participant Auth as Authoritative NS

    Client->>Resolver: Who is api.example.com?
    Resolver->>Root: Who handles .com?
    Root-->>Resolver: Try TLD NS at 192.5.6.30
    Resolver->>TLD: Who handles example.com?
    TLD-->>Resolver: Try Auth NS at 205.251.195.35
    Resolver->>Auth: What is api.example.com?
    Auth-->>Resolver: A record: 93.184.216.34 (TTL 300s)
    Resolver-->>Client: 93.184.216.34

DNS Record Types#

RecordPurposeExample
AMaps name to IPv4 addressapi.example.com → 93.184.216.34
AAAAMaps name to IPv6 addressapi.example.com → 2606:2800:220:1:...
CNAMEAlias to another domain namewww.example.com → example.com
MXMail server routingexample.com → mail.example.com
NSDelegates a zone to nameserversexample.com → ns1.provider.com
SRVService discovery (host + port)_http._tcp.example.com → 8080 web1
TXTArbitrary text (SPF, verification)v=spf1 include:_spf.google.com

DNS Caching Layers#

  1. Browser cache — respects TTL from response
  2. OS resolver cache — shared across all applications
  3. Router/ISP cache — intermediate caching resolver
  4. Recursive resolver — (e.g., 8.8.8.8, 1.1.1.1) caches per TTL

Design implication: Low TTLs (30–60s) enable fast failover but increase lookup latency. High TTLs (3600s+) improve performance but slow propagation of changes.


Transport Protocols: TCP vs UDP#

CharacteristicTCPUDP
ConnectionConnection-oriented (3-way handshake)Connectionless
ReliabilityGuaranteed delivery, ordering, retransmissionBest-effort, no guarantees
Flow controlYes (sliding window)No
Congestion controlYes (slow start, AIMD)No
Header size20–60 bytes8 bytes
Use casesHTTP, databases, file transferDNS, video streaming, gaming, VoIP
LatencyHigher (handshake + ACKs)Lower (fire and forget)

TCP Three-Way Handshake#

Client → Server:  SYN (seq=x)
Server → Client:  SYN-ACK (seq=y, ack=x+1)
Client → Server:  ACK (ack=y+1)

This adds 1 RTT before any data flows — a critical consideration for latency-sensitive systems.


HTTP Evolution#

HTTP/1.1 vs HTTP/2 vs HTTP/3#

FeatureHTTP/1.1HTTP/2HTTP/3
TransportTCPTCPQUIC (over UDP)
MultiplexingNo (one request per connection)Yes (streams over single connection)Yes (independent streams)
Head-of-line blockingYes (at TCP and HTTP level)Partial (TCP level remains)No (stream-independent)
Header compressionNoneHPACKQPACK
Server pushNoYesYes
Connection setupTCP + TLS = 2–3 RTTTCP + TLS = 2–3 RTT0–1 RTT (QUIC integrates TLS)
Binary framingNo (text-based)YesYes

HTTP/2 Multiplexing#

graph LR
    subgraph "HTTP/1.1 — 6 connections"
        C1[Conn 1: GET /style.css]
        C2[Conn 2: GET /app.js]
        C3[Conn 3: GET /image.png]
    end

    subgraph "HTTP/2 — 1 connection, multiple streams"
        S1[Stream 1: GET /style.css]
        S2[Stream 2: GET /app.js]
        S3[Stream 3: GET /image.png]
    end

When to Use What#

  • HTTP/1.1 — Legacy systems, simple proxies, environments without HTTP/2 support
  • HTTP/2 — Web applications, APIs, any client-server with modern TLS
  • HTTP/3 — Mobile clients (handles network switching), high-latency links, loss-prone networks

WebSockets#

WebSockets provide full-duplex, persistent connections over a single TCP socket. The connection begins as an HTTP upgrade:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

After the handshake, both client and server can send frames at any time without HTTP overhead.

Use cases: Chat applications, live dashboards, collaborative editing, gaming, real-time notifications.

Scaling challenge: Each WebSocket holds a persistent TCP connection, consuming server resources. You need connection-aware load balancing and often a pub/sub backbone (Redis Pub/Sub, Kafka) to broadcast across server instances.


Real-Time Communication Patterns#

PatternDirectionLatencyConnectionOverheadBest For
Short pollingClient → ServerHigh (interval-based)New connection each pollHighSimple dashboards, low-frequency updates
Long pollingClient → Server (held open)MediumHeld until data or timeoutMediumNotifications, moderate real-time needs
Server-Sent Events (SSE)Server → Client onlyLowPersistent HTTP connectionLowLive feeds, stock tickers, log streaming
WebSocketBidirectionalVery lowPersistent TCP socketVery low per messageChat, gaming, collaborative apps

Long Polling Flow#

1. Client sends request
2. Server holds connection open until data is available (or timeout)
3. Server responds with data
4. Client immediately sends a new request
5. Repeat

SSE vs WebSocket Decision#

  • Need bidirectional communication → WebSocket
  • Need server-to-client push only → SSE (simpler, auto-reconnect, works through HTTP proxies)
  • Need to work with HTTP/2 multiplexing naturally → SSE

API Paradigms: REST vs gRPC vs GraphQL#

AspectRESTgRPCGraphQL
ProtocolHTTP/1.1 or HTTP/2HTTP/2 (always)HTTP (typically POST)
Data formatJSON (text)Protocol Buffers (binary)JSON
ContractOpenAPI/Swagger (optional).proto files (required)Schema (required)
StreamingLimited (SSE, chunked)Bidirectional streamingSubscriptions (via WebSocket)
Code generationOptionalBuilt-in (multi-language)Client libraries
Browser supportNativeRequires grpc-web proxyNative
CachingHTTP caching (ETags, Cache-Control)No native HTTP cachingDifficult (single endpoint)
Over/under-fetchingCommon problemFixed by proto definitionSolved by design
Learning curveLowMediumMedium-High

When to Choose What#

REST — Public APIs, browser-first clients, simple CRUD, leveraging HTTP caching, team familiarity.

gRPC — Service-to-service communication, low-latency requirements, streaming needs, polyglot microservices, strict contracts.

GraphQL — Client-driven data requirements, mobile apps needing bandwidth efficiency, aggregating multiple backend services into one API, rapid frontend iteration.

gRPC Streaming Modes#

service ChatService {
  // Unary (request-response)
  rpc GetUser(UserRequest) returns (UserResponse);

  // Server streaming
  rpc ListMessages(ChannelRequest) returns (stream Message);

  // Client streaming
  rpc UploadFile(stream FileChunk) returns (UploadStatus);

  // Bidirectional streaming
  rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}

Protocol Selection Guide#

flowchart TD
    A[What are you building?] --> B{Public-facing API?}
    B -->|Yes| C{Need real-time?}
    B -->|No| D{Microservice-to-microservice?}

    C -->|No| E[REST + HTTP caching]
    C -->|Server push only| F[REST + SSE]
    C -->|Bidirectional| G[WebSocket]

    D -->|Yes| H{Need streaming?}
    H -->|Yes| I[gRPC]
    H -->|No| J{Low latency critical?}
    J -->|Yes| I
    J -->|No| K[REST or gRPC]

    A --> L{Client needs flexible queries?}
    L -->|Yes| M[GraphQL]

Key Takeaways#

  1. DNS is a distributed cache — TTL choices directly impact failover speed vs. lookup performance. Design for the trade-off your system needs.

  2. TCP guarantees delivery at the cost of latency — the 3-way handshake and retransmissions add overhead. HTTP/3 (QUIC) eliminates TCP’s head-of-line blocking.

  3. HTTP/2 multiplexing solves connection limits — but TCP-level head-of-line blocking remains. HTTP/3 solves this completely with independent QUIC streams.

  4. WebSockets are powerful but expensive — persistent connections consume server resources. Use SSE when you only need server-to-client push.

  5. REST is not always the answer — gRPC excels for internal services (performance, contracts, streaming). GraphQL excels when clients need flexible data fetching.

  6. Protocol choice cascades into infrastructure — gRPC requires HTTP/2-aware load balancers, WebSockets need sticky sessions or connection-aware routing, GraphQL complicates HTTP caching.

  7. Match the pattern to the problem — short polling for simplicity, long polling for moderate real-time, SSE for one-way streaming, WebSockets for full duplex.