SwadhyAI Notes

All System Design notes

System Design Networking

Network Protocols

First tokens on chatgpt.com should stream before the page feels stuck. To the user it feels like one action. Under the hood, the browser has to find the right server, open a path, encrypt the conversation, send the request, and keep receiving response chunks without making the page feel stuck.

Network protocols are the agreements that make that possible. Good system design is not memorizing every protocol name; it is knowing which agreement matters when search feels slow, a chat stream pauses, a mobile network drops packets, or a secure request must not be tampered with.

What happens first?

1

Find the server behind the name.

2

/

Open a path and handle packet loss.

3

Encrypt the conversation.

4

Send the message and stream response chunks.

One tap becomes many conversations

The user sees one search box or one chat input. Underneath, the client first asks, "Where is chatgpt.com or google.com?" answers with an . Then the client asks the server, "Can we talk?", , or another transport decides how that conversation starts and how lost packets are handled.

Before business data leaves the device, proves the server identity and encrypts the channel. Only after those setup steps does carry the actual meaning: method, path, headers, body, status code, caching rules, streaming behavior, and retry behavior.

That is why protocol choice appears in interviews. A search page needs low first-byte latency and aggressive caching. A chat product cares about a fast connection and smooth token streaming. A multiplayer game or video call may prefer dropping stale data over waiting for perfect delivery.

How to choose a protocol

1. Is every message important? For payments, orders, logins, and database writes, losing data is not acceptable. Use over because it delivers data reliably and in order.

2. Is old data still useful? In a video call, online game, or live cursor movement, a packet from 200 milliseconds ago may already be useless. In those cases, it can be better to skip stale data than to wait for perfect delivery.

3. Will real users be able to use it? Browsers, mobile networks, office firewalls, old apps, and CDNs may block or limit some protocols. The best protocol is the one that works reliably for the clients you actually have.

Simple rule of thumb

Start with . It is safe, widely supported, and correct for most APIs and websites. Change the protocol only when the product needs something specific: chat needs , video calls need , internal services may need , and mobile-heavy apps may benefit from .

In simple terms: do not pick a protocol because it sounds advanced. Pick it because it solves a real user problem.

Networking layers in simple language

Encapsulation means that each layer wraps the information from the layer above it. An HTTP request becomes bytes in a TCP stream; TCP segments carry portions of those bytes, IP packets carry the segments, and link-layer frames carry packets across each local hop. The receiving side removes those wrappers in reverse. A router normally forwards using IP information without interpreting your application’s JSON.

The layers provide different promises. IP attempts to move packets to a destination. TCP reconstructs an ordered byte stream using sequence numbers, acknowledgments, and retransmission. HTTP gives those bytes application meaning. None of those steps alone proves that a database transaction committed, so an application acknowledgment and a retry strategy are still necessary.

Think of layers as a way to follow one request from your app all the way down to signals on a wire or radio. When something breaks, layers help you ask: is this an app problem, a delivery problem, or a routing problem?

7
ApplicationHTTP, DNS, WebSockets, WebRTC, gRPC

What the product wants to do: search, chat, upload, pay, stream.

6
PresentationTLS, UTF-8, JSON, JPEG

How data is formatted, compressed, or encrypted before it is sent.

5
SessionSessions, RPC state, connection lifecycle

How a conversation is started, kept alive, resumed, or closed.

4
TransportTCP, UDP, QUIC

How bytes are delivered: reliably, quickly, in order, or with some loss allowed.

3
NetworkIPv4, IPv6, ICMP

How packets find the right machine across many networks.

2
Data LinkEthernet, Wi-Fi, ARP

How data moves across the next local hop, such as your Wi-Fi router.

1
PhysicalCables, fiber, radio

The actual signal: electricity, light, or radio waves.

What to focus on

For most system design problems, focus on three things: where the request goes (IP and routing), how data is delivered (TCP, UDP, QUIC), and what the app is saying (DNS, HTTP, WebSockets, gRPC). You usually do not need to discuss cables or hardware unless the problem is about data centers or networking infrastructure.

Simple shortcut

If seven layers feel too much, remember this simpler stack: app sends the request, transport delivers it, network routes it, and link/physical moves it across the next cable, Wi-Fi, or cellular hop.

What actually happens across the layers

L3: IP

This layer decides where packets should go. A public IP can be reached from the internet. A private IP usually works only inside your home network, office network, or cloud VPC.

Ask yourself: what address does the user connect to, and does a load balancer forward it somewhere else?

L4: TCP / UDP / QUIC

This layer decides how data is delivered. TCP provides an ordered byte stream by recovering missing data while the connection remains viable. UDP supplies datagrams without built-in delivery or ordering guarantees. QUIC builds reliable streams and congestion control over UDP, so using UDP underneath does not mean an application accepts lost data.

Ask yourself: is it more important to be reliable, or to stay realtime even if a few packets are lost?

L7: App protocols

This is the layer your product usually talks about. DNS finds the server. HTTP loads pages and APIs. WebSockets keep a chat-style connection open. WebRTC helps with calls and realtime media.

Ask yourself: is this a normal request, a live chat stream, or a realtime call?

IPv4 vs IPv6: how devices get addresses

Every device needs an address so packets know where to go. IPv4 is the older, still-common system. IPv6 is the newer one with far more addresses.

IPv4

Address size

4 bytes (32 bits)

byte 1
byte 2
byte 3
byte 4

192.168.1.1

  • • ~4.3 billion total addresses
  • • Dotted decimal notation
  • • Min header: 20 bytes
  • • Has checksum (slower router processing)

IPv6

Address size

16 bytes (128 bits)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

2001:0db8:85a3::8a2e:0370:7334

  • • 340 undecillion addresses (3.4 × 10³⁸)
  • • Hexadecimal colon notation
  • • Fixed header: 40 bytes
  • • No checksum (faster router processing)

Why did we need IPv6?

1. IPv4 exhaustion

4.3 billion addresses sounded like a lot in 1981. Today, a single household may have 20+ connected devices: phones, laptops, TVs, smart bulbs, and thermostats. IANA allocated the last IPv4 blocks in 2011.

2. NAT is a band-aid

We stretched IPv4 with , where many devices share one public IP. But NAT can break peer-to-peer connections, complicate gaming or voice calls, and add extra network work. It is a workaround, not a clean solution.

3. IoT explosion

Sensors, cameras, cars, industrial machines, and smart home devices all need network identities. IPv6 gives enough address space for this growth without forcing everything through shared IPv4 addresses.

FeatureIPv4IPv6
Address size32 bits (4 bytes)128 bits (16 bytes)
Total addresses~4.3 billion~3.4 × 10³⁸
Header size20-60 bytes (variable)40 bytes (fixed)
NAT required?Often yesNo: end-to-end
Built-in securityOptional (IPSec)Mandatory (IPSec)
Example192.168.1.12001:db8::1

Routers, IP addresses, and load balancers

Routers read the destination on each packet and choose the next step. A public IP is like a street address on the internet. A private IP is like a room number inside one building.

How routers work

Packet forwarding: A router reads the destination and sends the packet to the next network.

: This is the router's map. It tells the router which direction to send packets for each IP range.

Next-hop decision: A router does not plan the full journey. It only chooses the next step, then the next router continues from there.

: This is a safety counter. Every router reduces it by one. If it reaches zero, the packet is dropped so it cannot loop forever.

Public vs private IP

Public IP. Your internet address

This address can be reached from the internet. Your ISP or cloud provider assigns it. Example: 203.0.113.42

Private IP: address inside a network

This address works inside your home, office, or cloud network. The public internet cannot directly reach it. Your router uses to translate between private and public addresses.

Common private IP ranges

10.0.0.0/8: 16M addresses (large corps)

172.16.0.0/12: 1M addresses (medium)

192.168.0.0/16: 65K addresses (home)

How your request reaches a server

Your device
192.168.1.5
→
Home router
NAT
→
ISP router
Public IP
→
Internet
many hops
→
Load balancer
VIP
→
Server
10.0.1.42

Load balancers: traffic directors

A load balancer exposes one and spreads incoming traffic across many private backend servers. Clients do not need to know which server handled the request.

Routes using IP and port. It is fast because it does not inspect HTTP details. Example: cloud network load balancer.

Routes using HTTP details like path, headers, cookies, or host. It is smarter, but does more work per request.

Why VIP matters

DNS can point to one stable VIP while the platform adds or removes backend servers behind it. Scale changes without changing what users connect to.

Quick words you will see again

  • : where a device or service lives on the network.
  • : which app on that device should receive the data.
  • : careful delivery. Data arrives in order, and missing pieces are resent.
  • : how much data TCP is allowed to send at once before waiting for replies.
  • : fast delivery with fewer promises. Some packets may be late or lost.
  • : the lock on the connection. It encrypts data and helps prove the server is real.

How a TCP conversation starts and ends

Before useful data can move, spends a short hello exchange so both sides agree they are ready. When the conversation is over, each side says goodbye carefully so nothing is lost mid-sentence. That setup cost is the price of reliability.

Establishing Connection3-Way Handshake
CLIENTSERVER
SYN
→
seq=x
SYN-ACK
←
ack=x+1
ACK
→
ack=y+1
✓ DATA FLOWS
1

SYN: "Can we talk?"

The client starts the conversation and proposes a starting number so both sides can track the bytes that follow.

2

SYN-ACK: "Yes, I am ready too."

The server answers yes, confirms the client's hello, and shares its own starting number.

3

ACK: "Perfect, let's begin."

The client confirms the server's hello. Now both sides are lined up and useful data can flow.

Why this matters: this hello costs about one and a half before your app data starts. Add encryption and you wait even longer on a brand-new connection.
Terminating Connection4-Way Shutdown
INITIATORRESPONDER
FIN
→
I'm done
ACK
←
Got it
FIN
←
Me too
ACK
→
OK, bye
⏳ TIME_WAIT (60s)
1

FIN: "I am done sending."

One side says it has finished speaking. It can still listen for anything left to arrive.

2

ACK: "Got it."

The other side confirms. The conversation is half closed: one direction is finished, the other may still send.

3

FIN: "I am done too."

After sending anything left, the second side also says goodbye.

4

ACK + TIME_WAIT: "Okay, I will wait a moment."

The first side confirms the goodbye and waits briefly so late packets do not confuse a brand-new connection that reuses the same numbers.

At big scale: many short connections can leave a huge pile of waiting sockets. Teams usually reuse connections instead of opening a brand-new conversation for every tiny request.

Why new connections feel slow

Every brand-new conversation pays a hello tax before useful data starts. Nearby servers feel this less. Distant users feel it a lot:

Same datacenter

~0.75 ms

0.5ms RTT × 1.5 = 0.75ms

Same region (US-East)

~30 ms

20ms RTT × 1.5 = 30ms

Cross-continent (US→EU)

~150 ms

100ms RTT × 1.5 = 150ms

So reuse connections when you can. Keep an existing path warm for the next request instead of saying hello from scratch every time. That is why keep-alive and connection pools matter for ChatGPT streams, search pages, and APIs.

A simple web request, end to end

One browser click feels like a single GET. Underneath, it is a short story: find the address, say hello, exchange the HTTP request and response, then say goodbye. Many packets hide behind one conceptual request.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    autonumber
    participant Browser
    participant DNS
    participant Server

    Browser->>DNS: Resolve example.com
    DNS-->>Browser: Destination IP
    Browser->>Server: SYN
    Server-->>Browser: SYN-ACK
    Browser->>Server: ACK (TCP ready)
    Browser->>Server: HTTP request (GET / path, headers)
    Server-->>Browser: HTTP response (status, headers, body)
    Browser->>Server: FIN
    Server-->>Browser: ACK
    Server->>Browser: FIN
    Browser-->>Server: ACK (connection closed)

What your app sees

An ordered stream of bytes. TCP handles missing pieces and reordering so you can focus on request and response logic.

One click, many packets

DNS, the TCP hello, HTTP pieces, acknowledgements, and goodbye steps can easily become dozens of packets.

Why connections cost

Each live session uses memory and CPU. A fresh hello adds wait time before useful data. Idle connections still hold resources.

Reuse when you can

Keep-alive reuses the same pipe for later requests. HTTP/2 can share many requests on one connection instead of opening several.

How TCP learns a safe sending speed

The internet is shared. If every app blasts data as fast as possible, routers overflow and everyone slows down. tries to find a safe speed: send a bit more when the path looks healthy, and back off when the network starts struggling.

Why it exists: links and routers have limited room. TCP keeps adjusting its send rate so one connection does not flood the path.

The main knob is : the congestion window. Think of it as "how many bytes may be in flight before I wait for replies."

Two useful words: MSS is roughly the biggest useful packet chunk on this path. is the round-trip time for a send and its reply.

Classic TCP: start carefully, then grow gently

Imagine turning on a tap slowly. TCP begins carefully, speeds up while replies look healthy, then grows more gently once it thinks it is near the limit.

  1. Slow start: begin with a small send window so you do not flood a weak path. If replies keep arriving, TCP ramps up quickly.
  2. Congestion avoidance: after a threshold, growth becomes careful. TCP tops off the path instead of doubling again and again.
  3. On trouble: if packets are lost, classic TCP treats that as "I was too fast" and cuts its send window sharply, then climbs again.

Phase 1: Slow start

  • cwnd starts small (often ~10 MSS today; older textbooks often assume 1 MSS).
  • While ACKs look healthy, cwnd ramps fast: about doubles per RTT in simple Reno sketches.

Phase 2: Congestion avoidance (past ssthresh)

  • Growth becomes cautious: about +1 MSS per RTT in the textbook Reno picture.
  • You are "topping off" the pipe instead of aggressively probing.

On loss: multiplicative decrease (classic view)

Loss is read as "you exceeded capacity". So cwnd is cut sharply (for example cwnd := cwnd / 2 in simple sketches) before cautiously growing again.

Why this matters: a brand-new connection does not instantly use the full pipe. It needs a few round trips to warm up. That is another reason to reuse connections for search pages, APIs, and streaming chats.

: measure the path, do not only react to loss

Classic often assumes "a lost packet means the path is full." On mobile networks and busy links, that guess can be wrong, so the connection stays slower than it needs to be.

tries a different story. It estimates how fast the path can really deliver data and how long a healthy should take, then paces sends near that speed instead of waiting for packets to disappear.

Loss-based TCP (Reno-style intuition)

"If packets disappear, I was too aggressive → slash cwnd."

BBR (high-level intuition)

"Estimate max sustainable delivery rate and baseline RTT; pace sends near the bottleneck and avoid building giant standing queues."

Simple takeaway: classic TCP mostly reacts to packet loss. BBR tries to measure the real path speed and delay. That can help on mobile, long-distance, and video-heavy paths.

TCP: the careful default for most traffic

Most of the internet prefers because missing data is usually worse than waiting a little. If every byte must arrive in order, TCP is the usual starting point.

Where you see TCP every day

🌐

Web (HTTP/HTTPS)

📧

Email (SMTP/IMAP)

📁

File transfer (FTP/SFTP)

🗄️

Databases (MySQL, Postgres)

🔐

SSH / Remote access

🔗

APIs (REST, gRPC)

💬

Chat (WebSocket)

💳

Payments (TLS)

If your app needs every byte to arrive, in order, start with . That is why it carries most internet traffic, including , , and .

What reliability costs

Speed takes time to warm up

A new connection does not instantly use the full path. TCP starts carefully and ramps up while replies look healthy.

Waiting before the first byte

The hello and steps can take a few . Also, one lost packet can pause the whole stream until that piece is resent.

What TCP does not promise

TCP also does not preserve application message boundaries. If an application writes two messages, a receiver may read them together or in several pieces. Protocols therefore need framing, such as a length prefix, delimiters, or an existing HTTP message format. A TCP acknowledgment confirms receipt by the peer’s transport stack, not that application code has validated, processed, or permanently stored the message.

An ACK does not mean "saved to disk."

It only means the bytes reached the other machine's network stack. The app could still crash before it finishes processing or writing them.

For durability, the application still needs its own save step, like a database commit that flushes to disk. TCP gives delivery across the network, not permanent storage.

When a packet goes missing

tries to fill the gaps so the final stream still arrives complete and in order:

1. Wait, then resend

If no reply arrives in time, TCP sends the packet again. Each wait gets longer so a busy network is not flooded.

2. Resend sooner

If the receiver keeps saying "I am still waiting for the same piece," TCP assumes that piece is lost and resends quickly.

3. Resend only what is missing

The receiver can say exactly which pieces arrived, so TCP only replaces the gaps.

TCP vs UDP in plain words

Think of two ways to send news across town. is careful and checks that every piece arrived in order. is quick and light: it sends each piece and moves on, even if a few never arrive.

TCP = tracked delivery

You send something important and wait for confirmation. If a piece is missing, it is sent again. Slower, but you can trust the final result.

UDP = send and keep going

You send updates quickly without waiting for receipts. A missing update is okay if the next one is more useful anyway, like the newest game position or voice sample.

FeatureTCPUDP
SetupSays hello firstJust sends
ReliabilityDelivers in order, fills gapsBest effort; gaps may remain
Extra overheadLarger headers, more bookkeepingVery small headers
Sharing the networkSlows down when the path is busyNo built-in slowdown
One lost packetCan pause the whole streamOther packets keep moving
Who fixes loss?TCP itselfYour app, or nobody
In the browserEasy (HTTP, WebSocket)Only through WebRTC or HTTP/3
Simple pictureTracked deliverySend and keep going
Common usesWeb, email, files, databases, SSHGames, calls, DNS, live video, QUIC

When UDP is the better story

is useful when waiting for a missing packet would hurt more than skipping it. There is no long hello, and the protocol itself does not promise delivery. Your app decides what to do if something never arrives.

What apps usually do with gaps

Games

Positions arrive many times per second. An old missed update is useless. The next packet already has the current place.

Voice and video calls

A tiny glitch is often better than a long freeze while the network resends old audio. often uses UDP here.

A lookup is often one small question and one small answer. If nothing comes back, just ask again.

A live game example

You are watching a live match and one tiny video piece is lost.

Careful thinking

Stop and wait for the missing piece. The stream freezes, and by the time it arrives the moment may already be over.

Live thinking

Skip the tiny glitch and keep playing. You stay with the live moment instead of waiting for yesterday's frame.

Browsers do not expose raw UDP

Regular JavaScript cannot open a raw socket. That is mostly a safety choice. Video calls still use UDP under the hood through , and uses UDP inside the browser engine. For most web apps, you still work with -based or unless you use those special paths.

A simple way to choose

Prefer when…

  • Every byte matters (files, payments, databases)
  • Order matters (chat, logs)
  • You want easy browser support
  • You do not want to invent reliability yourself

Prefer when…

  • Old data is worse than missing data (game positions)
  • Freshness matters more than perfection (calls)
  • The message fits in one small packet ()
  • You control both ends and can build your own rules ()

How to choose UDP (and when to mix)

Choose UDP when late data is worse than missing data. Even then, browsers and mixed systems often still use TCP for setup, auth, and control.

UDP-friendly jobs

  • Calls, live video, and interactive games
  • Telemetry where the next sample replaces the last
  • Tiny one-packet questions like classic DNS
  • Custom reliability stacks such as QUIC when you control both ends

Caveats and mixed designs

  • Browser JavaScript cannot open raw UDP; use WebRTC or HTTP/3
  • Common pattern: TCP/HTTP for signaling and auth, UDP/WebRTC for media
  • Use a reliable application protocol for state-changing APIs; HTTPS over HTTP/3 is reliable too.
  • A custom UDP protocol also needs congestion control, pacing, and limits on retransmission.

How HTTP got faster: 1.1 → 2 → 3

The meaning of stayed familiar: methods, paths, headers, status codes. What changed is how those requests share a connection and how quickly can start, especially on busy pages and mobile networks.

  • Can reuse one connection for many requests
  • Responses on one connection still wait in order
  • Browsers often open several connections to work around that

  • Many requests share one connection at the same time
  • Headers shrink after the first time they appear
  • One lost TCP packet can still pause everything on that connection

  • Runs on over instead of TCP
  • Repeat visits can start sending useful data sooner
  • One lost packet hurts one stream, not the whole page load
  • Can keep going when a phone switches from Wi‑Fi to cellular

HTTP/2: many requests, one conversation

breaks traffic into small frames so several requests can share one connection. A slow response no longer has to block every other response on that same pipe.

Before:

Browsers often open several TCP connections. On each one, responses still wait in line. If the first response is slow, the others behind it wait too.

After:

Many requests share one connection. Pieces of different responses can arrive interleaved, so one slow file does not freeze the whole page load as easily.

Server push

After you ask for a page, the server may send CSS or JS it knows you will need next. Helpful in theory; in practice, caching makes this less common than multiplexing itself.

Smaller headers

The first time a long header appears, it is remembered. Later requests can send a short reference instead of repeating cookies and user-agent strings every time.

HTTP/3 and QUIC: fewer freezes on bad networks

QUIC runs over UDP but provides its own reliable streams, encryption, loss recovery, and congestion control. Consequently, HTTP/3 is suitable for reliable API traffic; “uses UDP” does not mean “loses application requests without recovery.” Stream independence prevents missing bytes in one stream from blocking delivery of unrelated streams, although all streams still share connection-level resources and congestion conditions.

still feels like to your app, but it rides on over . That matters most when the network is lossy or a phone switches networks mid-session.

Why people like QUIC

  • Repeat visits can start useful data sooner
  • A lost packet hurts one stream, not every download on the connection
  • A phone can keep the conversation alive when its changes
  • Encryption is built into the transport, not bolted on afterward

Starting sooner on a return visit

Older + path

Say hello, prove identity, then finally send the request. Several can pass first.

on a repeat visit

If the client already knows the server, useful data can ride in the first packet.

Where QUIC fits in the story

QUIC provides reliable streams, congestion control, and encryption over UDP. HTTP/3 uses these streams to carry HTTP requests and responses. The useful distinction is between losing data within one stream and making unrelated streams wait for that same loss.

What it is

Reliable, shared, encrypted streams over UDP. HTTP/3 is normal HTTP meaning riding on QUIC instead of TCP.

Why it helps

Faster return visits, better behavior when a phone changes networks, and less freezing across unrelated downloads.

What not to do

Do not redesign everything around QUIC. Turn it on at the edge when useful, and keep most API design on plain HTTP semantics.

TLS 1.3: the lock starts sooner

is how the client and server agree on secret keys and prove the server is real. Newer TLS spends fewer on that hello, so encrypted data can begin sooner. That is why feels snappier with TLS 1.3.

TLS 1.2

More back-and-forth before the channel is ready. Encryption starts later.

Client says hello

Server answers with certificate and key material

Client finishes key setup

Server confirms

Then encryption is ready

TLS 1.3

Key ideas travel earlier, so one round trip is often enough for a fresh connection.

Client says hello and shares key material

Server answers with key material, certificate, and finish

Client confirms

Encryption is already underway

What to remember

  • Fresh connections usually need fewer waits than TLS 1.2
  • Return visits can resume even faster
  • Old weak algorithms were removed
  • More of the handshake itself is protected

DNS: turning a name into an address

The client usually asks a recursive resolver, which answers from cache or queries the DNS hierarchy until it reaches an authoritative server for the name. A hostname can map to several addresses and those answers can change. The TTL tells caches how long an answer can be reused; it does not force an already-open TCP connection to reconnect. During a migration, account for cached answers and existing connections separately.

When you type a site name, your device asks for the matching . It usually checks nearby caches first, then asks farther helpers until an authoritative answer arrives.

Browser cache→OS cache→Router cache→ISP resolver→Root→.com / TLD→Authoritative
RecordWhat it mapsWhy it matters
Aname → IPv4Most common web lookup
AAAAname → IPv6Newer address family
CNAMEalias → real nameOften used with CDNs
SRVservice → host + portFinding a service, not just a site
can also steer traffic: give different regions different answers, send a little traffic to a canary version, or prefer the nearest healthy data center.

Rough latency numbers that keep you honest

These are ballpark times, not exact lab measurements. Use them to ask: is this delay from memory, disk, the same region, or another continent?

OperationLatencyNotes
L1 cache reference0.5 ns
L2 cache reference7 ns14x L1
Main memory reference100 ns200x L1
SSD random read16 μs150x memory
HDD random read2 ms20,000x memory
Same-datacenter round trip0.5 ms
Redis/Memcached GET0.1-0.5 msnetwork + lookup
Read 1 MB from SSD1 ms
Cross-region round trip (US-EU)70-150 ms
TCP handshake1.5 RTT~1-225ms
TLS 1.3 handshake1 RTT~1-150ms
QUIC 0-RTT (repeat)0 RTTinstant!
DNS lookup (uncached)20-120 ms
What to remember: distance often beats clever code. A nearby cache hit can be tiny. A cross-region hop can be huge. Smaller responses also help, because every byte still has to travel.

UDP in the real world

The pattern is the same in different products: if waiting for a missing packet ruins the experience, send quickly and let the app decide what to do with gaps.

Video

Many on-demand streams still use with adaptive quality. Live calls and some live streams prefer because a tiny glitch is better than a long freeze.

Games

Position updates arrive many times per second. An old missed update is less useful than the newest one that just arrived.

and

DNS often fits in one small question and answer, so UDP is a natural fit. QUIC then builds careful streams on top of UDP for .

Which protocol fits which job?

Start from the job, not from the newest acronym. Ask whether you need perfect delivery, low delay, browser support, or control of both ends.

Use CaseProtocolWhy
Public REST APIHTTP/2 + TLS 1.3Works almost everywhere; easy to cache
Internal servicesgRPC (HTTP/2)Typed, compact, good for streaming
Realtime chatWebSocketsBoth sides can talk anytime
Live notificationsSSE over HTTPServer pushes updates; simple reconnect
VideoHLS/DASH or UDP/WebRTCOn-demand vs live call needs differ
Online gamesCustom UDPNewest update matters more than old ones
Mobile-heavy APIHTTP/3 (QUIC)Handles network switches and loss better
IoT telemetryLightweight messaging over TCPSmall messages, publish/subscribe style

How to debug network problems calmly

Measure a timeline before changing protocols: DNS lookup, connection establishment, TLS negotiation, request upload, time to first response byte, and response download. A slow first byte with fast setup may indicate application queuing or database work; a slow large download may indicate bandwidth or loss. Compare cold and reused connections, and check whether a proxy introduces its own timeout. This separates a network symptom from a server bottleneck.

A vague "it is slow" becomes clearer when you split the path into names, connection setup, encryption, transport health, and the app itself.

Ask in order

  • Did point to the place you expected?
  • Did or and finish cleanly?
  • Are packets being lost or resent?
  • Is a proxy buffering, rewriting, or timing out?
  • Is the app failing fast, or waiting forever upstream?

Measure the pieces

  • DNS time, connect time, TLS time, time to first byte, download time
  • Which version clients actually use
  • Retries, resets, timeouts, and packet loss
  • Cache hits, response size, and connection reuse
  • Client world: browser, mobile network, corporate proxy

Where time goes in one request

A user action is a chain of waits: find the name, open a connection, encrypt, send the request, do server work, download the response, then render.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    autonumber
    participant Client
    participant DNS
    participant Edge as Edge or proxy
    participant App as Application tier
    participant Data as Cache or database

    Client->>DNS: Resolve host, often cached
    DNS-->>Client: Address from DNS records or traffic policy
    Client->>Edge: TCP 3-way handshake or QUIC setup
    Client->>Edge: TLS handshake and protocol negotiation
    Client->>Edge: Send headers and optional body
    Edge->>App: Reuse pooled upstream connection
    App->>Data: Read, write, or cache lookup
    Data-->>App: Result
    App-->>Edge: Status, headers, body
    Edge-->>Client: Compressed response bytes
    Client->>Client: Parse, execute, render, cache

Setup

A cold DNS lookup, TCP hello, and TLS check can burn one or more round trips before your app code even runs.

Bytes

Big cookies, fat headers, and large JSON bodies make upload and download slower. Compression and smaller payloads help.

Client world

Browsers add rules and limits. Phones add radio wake-up, loss, and network switches.

Cold start

DNS + TCP + TLS can easily cost a few hundred milliseconds on a 100ms path before useful request bytes finish setup.

Warm connection

A reused HTTPS connection can send immediately and skip most of that setup tax.

Header bloat

Large cookies and auth headers add cost on every request, even before the body starts.

Smaller bodies

If a 50 KB JSON response compresses to 10 KB, transfer size falls by 40 KB. The client still decompresses and parses the original JSON structure, so compression alone does not reduce JSON parsing work. Removing unneeded fields can reduce both transferred data and parsing effort.

Why reusing a connection feels so much faster

Saying hello once and keeping the pipe warm beats paying the hello tax on every request, especially when latency is high or you make many calls.

Without reuse

Twenty separate cold calls can burn seconds just on setup if they cannot overlap well.

With keep-alive

The first call pays setup. The next ones mostly pay for server work and moving the payload.

With multiplexing

Many requests can share one encrypted connection at once, which is how modern pages stay efficient.

Simple rule of thumb: if only the first request after idle is slow, look at DNS, TLS, cold pools, or mobile radio wake-up before blaming the database.

Your app vs the plumbing underneath

Your code talks in HTTP or gRPC meaning. Underneath, sockets, packets, and congestion control move the bytes. Keep those two stories separate and systems get easier to reason about.

Your app

  • Methods, paths, bodies, status codes, auth
  • Retries, timeouts, and business rules
  • Choosing HTTP, WebSockets, gRPC, or custom framing

The transport

  • IP routing, TCP or UDP behavior, congestion windows
  • Buffers, resends, and whether loss pauses one stream or everything
  • QUIC may live in userspace, but the idea is the same: meaning vs packet plumbing
Good default: start with TCP + HTTP(S) unless delay, loss tolerance, or browser limits clearly push you toward UDP, WebRTC, or a special stack.

Try it: watch one request in packets

A packet capture turns the story into evidence. You can see where time went: name lookup, hello, encryption, first response, or lost packets.

  1. Run curl -v https://example.com/api/health once cold, then again within a minute while the connection is still warm.
  2. Capture traffic with Wireshark or tcpdump, filtered to your host on tcp port 443.
  3. Mark , the hello, the hello, and the first request and response.
  4. Compare cold vs warm: how many waits disappear when the connection is reused?
  5. Look for retransmits. Loss often shows up in the capture before your app logs a timeout.
What to remember: name the bottleneck first: , connect/, server think time, or download: before jumping to , a CDN, or a redesign.

Correctness invariant

What must never become false

Once you pick a transport for a message class, its delivery contract stays fixed for that class: reliability (retransmit transport data, while application outcomes may remain uncertain after a timeout), order (byte-stream vs datagram), and latency budget (wait-and-retransmit vs drop-and-continue). Do not silently switch a payment or login path to best-effort , or a live frame path to "must wait for every lost packet" , without changing the product promise users see.

Quantitative example: handshake tax on a 100 ms path

Suppose client ↔ edge is 100 ms. In a simplified loss-free model, a cold connection costs about 1 RTT before the client can send its TLS handshake, then 1.3 costs about 1 more RTT before ordinary application data: roughly 200 ms of setup. The request and first response byte add about another RTT, giving roughly 300 ms before server processing and DNS. Twenty sequential cold calls repeat that setup cost; parallel calls overlap it, so their wall times must not simply be added. Keep-alive / multiplexing pays that tax once; 0-RTT on a resumed path can reduce setup waiting only for operations permitted by the application’s replay policy. Early data can be replayed and may be rejected by the server. By contrast, a live game tick over may accept a 1–2% packet loss rather than adding one extra RTT of retransmit delay that makes the update stale.

Failure timeline: loss, HOL blocking, then timeout

T+0      Client sends HTTP/2 stream A (CSS) and stream B (API JSON) on one TCP
T+20ms   One TCP segment carrying stream-A bytes is lost on the path
T+40ms   Stream B's packets arrive at the kernel, but TCP holds them (HOL)
T+120ms  Illustrative loss-detection point; TCP retransmits the missing segment
T+140ms  Stream B reaches its application deadline while bytes are still blocked
T+160ms  Missing bytes arrive; transport delivery resumes after B has timed out
Outcome  One lost packet delayed an unrelated request; user sees timeout, not "CSS slow"

That is TCP head-of-line blocking under multiplexing. / keeps per-stream loss from freezing sibling streams, but loss still costs retransmit delay on the affected stream.

Try it: TCP recovery versus UDP exposure to loss

Adjust loss, pick TCP or UDP, and send bursts. TCP pays extra round trips to repair the stream; UDP leaves gaps for your application to detect.

No packets yet. Send a burst to populate the timeline.

Green means the receiver got the payload. Amber marks a TCP retransmit attempt. Red marks a UDP datagram the application must treat as missing.
Delivered
0
UDP drops
0
TCP retransmits
0
Total events logged
0

TCP retransmits until each segment is acknowledged or the connection gives up. UDP exposes loss to the application immediately.

Exercises

1. Choose the transport contract

You ship a payment confirm API and a 30 fps spectator video feed. For each, state reliability, order, and max acceptable extra delay on 2% loss. Which stack (TCP+TLS+HTTP/2, QUIC/HTTP/3, custom UDP) fits, and what must never become false if you get it wrong?

2. Cold-start budget math

RTT = 80 ms. Estimate time-to-first-byte for: cold TCP+TLS 1.3; warm keep-alive; QUIC 0-RTT resume. Your SLO is TTFB p95 < 200 ms. Which setups pass, and how many parallel cold connections break the budget?

3. Timeout vs retransmit

Client timeout is 100 ms; path RTT is 60 ms; one segment is lost. Will the app timeout before TCP's first retransmit lands? What do you change first: timeout, connection reuse, or protocol (HTTP/2 → HTTP/3)?

Primary references

Protocol primary sources, not generic interview books.

What to take with you

Start with and for most products. Reuse connections so you are not paying the hello tax again and again. Use when many requests share one path, and when mobile loss or network switches matter. Remember that is often the first steering point, and that one saved compounds across a huge audience.

Practice and further reading

Use these exercises to connect the lesson to a design decision. State your assumptions, trace what happens to one request, and explain the rule that must remain true even during a failure. That rule is the design's correctness invariant.

Focus for this lesson: Choose transport and application protocols from delivery, ordering, congestion, latency, middlebox, security, and evolution requirements.

Explain the decision

When is UDP preferable even though it does not guarantee delivery?

Read the reasoning

When the application can tolerate or repair loss and values message boundaries or avoiding head-of-line blocking, as in realtime media or custom transports such as QUIC.

Apply it to a production scenario

Users report good server latency but slow page loads only on lossy mobile networks. What protocol path do you inspect?

Read one approach

Compare DNS, TCP/TLS setup, retransmission, HTTP/2 connection-level loss effects, QUIC recovery, MTU, and radio handover behavior.

Work through the numbers

Estimate cold HTTPS setup on a 90 ms RTT path using DNS, TCP, and TLS 1.3 before the request.

Read the worked calculation

A simplified serial budget is roughly 3 RTT = 270 ms before server work; resumption, cached DNS, and QUIC can change the count.

Reason through a failure

What must a protocol migration preserve?

Read the recovery reasoning

Authentication, ordering assumptions, retry semantics, observability, and fallback behavior across old clients and intermediaries.