Networking Foundations
How computers actually find and talk to each other
Your code passes every test on your laptop. You ship it. Within an hour a user in Mumbai files a ticket: "the page spins forever." Nothing in your codebase changed — the only new variable is distance, and the network in between.
Almost every system design problem eventually bottoms out in one question: what happens to a request between the moment a user taps a button and the moment your server sees it? The six ideas below trace that journey in order. Caches, queues, shards, all the heavier machinery later in this book sits on top of them.
The six networking primitives every backend engineer is assumed to know: the client–server model, IP addresses, DNS, proxies vs reverse proxies, latency, and HTTP/HTTPS. Every concept ends with a QA testing lens: how a tester would probe or break it.
The Client–Server Model
Strip away every diagram and you're left with two roles: someone who asks, and someone who answers. The browser, the mobile app, the smart TV, even another backend service — anything that initiates a request is a client. The thing that listens, does the work, and replies is the server.
The quiet power of this split is independence. Because the client and server only agree on a contract (the request/response shape), you can rebuild the mobile app without touching the backend, or replace your monolith with microservices without the client ever noticing. The contract is the boundary; everything on either side is free to change.
QA Lens
The contract is exactly what you test. Pin the request/response shape in a contract test (e.g.
Pact) so the server can't silently drop a field the app still reads. The classic production
incident: backend renames user_name to username, all server tests
pass, and every mobile client shows a blank profile.
A client never trusts a server's uptime, and a server never trusts a client's input. Design as if both will misbehave.
IP Addresses — the street address of every machine
For one machine to send bytes to another, it needs to know where to send them. That "where" is an IP address: a unique number identifying a device on a network.
- 32-bit — about 4.3 billion addresses
- Human-readable, four 0–255 octets
- Address space effectively exhausted
- Still dominant on the public web
- 128-bit — a practically unlimited pool
- No NAT gymnastics required
- Built-in support in all modern stacks
- Adoption growing, not yet universal
For system design you rarely care about the bits. You care that every server, load balancer, cache node, and database replica has an address that something else uses to reach it. When you draw boxes and arrows, each arrow is one machine resolving and dialing another machine's IP.
QA Lens
Hardcoded IPs are time bombs in test suites. A config or fixture that pins
10.0.3.17 instead of a hostname passes for months — until the environment is
rebuilt and every test fails with connection errors nobody can explain. Audit test configs for
raw IPs, and test IPv6 paths explicitly: a service bound only to 0.0.0.0 (IPv4)
will silently refuse IPv6 clients your users increasingly are.
But nobody types 142.250.80.46 to reach Google. Something translates the name. That something
is DNS.
DNS — the internet's phone book
DNS (Domain Name System) turns a human name like qasecret.dev into a machine-routable IP
address. It is a cache-heavy, multi-step lookup that you almost never see — until it fails, at
which point your entire site is "down" while every server is perfectly healthy.
Note the shape of the conversation: the root server doesn't forward your question to the TLD — it hands the resolver a referral ("ask them"), and the resolver does the next hop itself. This iterative lookup is why the resolver's cache is so valuable: one resolved answer spares every later client the whole tour.
The result is cached at every hop — browser, OS, resolver — each with its own TTL (time-to-live). That's why the first visit to a new domain feels a beat slower and every visit after is instant. It's also why a DNS change "takes time to propagate": you're waiting for old cached answers to expire around the world.
DNS quietly doubles as infrastructure glue:
| DNS trick | What it buys you |
|---|---|
| Return different IPs for one name | Crude geographic / round-robin load balancing |
| Drop a failing IP from the record | Failover to a healthy region or backup |
| Low TTL on critical records | Faster failover, at the cost of more lookups |
| High TTL on static records | Fewer lookups, slower changes |
QA Lens
DNS bugs masquerade as everything else. Before blaming the app, confirm resolution with
dig / nslookup from the failing region. In test environments, a stale
/etc/hosts entry or an over-long TTL is a top cause of "works on my machine":
your box resolves to the old server while CI resolves to the new one.
Proxy vs Reverse Proxy — same word, opposite jobs
A proxy is a middleman that sits in the request path. The confusing part is that the word covers two opposite roles depending on which side it protects.
- Forward Proxy (shields clients)
- Reverse Proxy (shields servers)
A forward proxy stands in front of clients. The server only ever sees the proxy's address, never yours.
Privacy & anonymity (VPN, corporate egress)
Content filtering and access policy
Bypassing geo-restrictions
Adds a hop; can become a chokepoint for all client traffic
A reverse proxy stands in front of servers. The client thinks it's talking to one machine; behind the curtain the proxy fans requests out to a fleet.
SSL/TLS termination in one place
Load balancing, caching, compression
Hides your topology from the outside world
One more component to make highly available
The mnemonic that sticks: a forward proxy answers "who is this client?" with a lie to protect the client. A reverse proxy answers "where is the real server?" with a lie to protect the servers. Nginx and HAProxy almost always show up wearing the reverse-proxy hat.
QA Lens
Reverse proxies rewrite things — headers, paths, the client IP. When a test asserts on the
caller's IP, remember the app now sees the proxy's address unless
X-Forwarded-For is honored. SSL termination at the proxy is another gotcha: the
app speaks plain HTTP internally, so "is it encrypted?" must be verified at the edge, not at
the service.
Latency — the tax you can't refuse
Latency is the time data takes to get from A to B, measured in milliseconds. It is the single number users feel, even when they can't name it.
Latency isn't one thing — it's a stack of unavoidable costs:
You can't out-engineer physics, so the playbook is always to move the work closer or skip it entirely: CDNs serve from edge nodes near the user, caches avoid the round trip to the database, and regional deployments shrink the geographic distance. Reducing latency is one of the most common non-functional requirements you'll be handed.
"We have plenty of bandwidth, so latency isn't a problem." Bandwidth is how much data moves per second; latency is how long one round trip takes. A 10 Gbps link between Mumbai and New York still costs ~180ms per round trip — and an API call that makes five sequential round trips pays that tax five times. You buy bandwidth; you engineer around latency.
QA Lens Averages lie. A p50 of 80ms can hide a p99 of 4 seconds — and the p99 is the user writing the angry review. Always measure latency as a distribution (p50/p95/p99), and test from the regions your users actually live in, not from the data center next door to your runners.
HTTP / HTTPS — the language on the wire
Once a client has found a server and a route, they need a shared language. HTTP defines how requests and responses are structured; HTTPS is the same protocol wrapped in TLS so nobody in the middle can read or tamper with it.
The defining trait of HTTP is that it is stateless: each request stands alone and the server remembers nothing about the last one. That's a gift for scaling — any server can handle any request — but it means state (who you are, what's in your cart) has to be carried explicitly via cookies, tokens, or sessions.
The interview-ready checklist:
| Concept | What to know |
|---|---|
| Methods | GET (read), POST (create), PUT/PATCH (update), DELETE (remove) |
| Status codes | 2xx success · 3xx redirect · 4xx client error · 5xx server error |
| Headers | Auth (Authorization), caching (Cache-Control), content type, cookies |
| HTTPS cost | One extra round trip for the TLS handshake (TLS 1.3; older TLS 1.2 needs two) — protects data in transit |
QA Lens
Status codes are your cheapest contract. A search that returns "no results" should be
200 with an empty list, not 404 — clients branch on the code. Test
the unhappy paths explicitly: 401 vs 403, 400 on bad
input, 429 when rate-limited. And verify HTTPS redirects: an endpoint that also
answers plain HTTP is a downgrade attack waiting to happen.
Putting It Together: One Request, Six Concepts
When you tap a link, all six ideas fire in sequence. Click any step to see its job.
Test Yourself
Answer from memory first, then expand to check.
Q1. Your site is "down" for users in one country, but every server dashboard is green. Which layer do you suspect first, and what command confirms it?
DNS. A bad or stale record (or a regional resolver still caching an old IP) makes a perfectly
healthy site unreachable. Confirm with dig / nslookup from the failing region and compare
the answer to the IP your servers actually have.
Q2. A forward proxy and a reverse proxy both sit "in the middle." What's the one-line difference?
A forward proxy stands in front of clients and hides them from servers; a reverse proxy stands in front of servers and hides them from clients. Nginx in front of your backend fleet is a reverse proxy.
Q3. Your p50 latency is 80ms and the team celebrates. Why might users still be furious?
p50 is the median — half of all requests. The p99 can simultaneously be 4 seconds, which means 1 in 100 requests (often your busiest users' requests) feels broken. Always look at the distribution, not the average.
Q4. Why does HTTP being stateless make horizontal scaling easier — and what problem does it create?
Stateless means any server can handle any request, so you can add servers freely behind a load balancer. The cost: identity and session state must be carried explicitly (cookies, tokens) or stored in a shared store — the server remembers nothing between requests.
Quick Revision
One asks, one answers. The contract between them is the only fixed thing.
Every machine in your diagram has one. Arrows = machines dialing IPs.
Name → IP, cached at every hop. Also does load balancing and failover.
Forward shields clients; reverse shields servers and does TLS, caching, LB.
Propagation + serialization + processing + queuing. Measure p99, not averages.
Stateless protocol; HTTPS adds a TLS handshake. Status codes are a contract.
Name-drop these correctly and you sound senior fast: "I'll terminate TLS at the reverse proxy, use DNS-based failover across regions, and put a CDN in front to cut propagation latency for read traffic." Six words, three trade-offs.
Where to Next
You now know how bytes find a server. Next, learn the contracts those bytes carry:
- APIs & Communication — REST, GraphQL, WebSockets, and Webhooks
- What is System Design? — the mental model that ties it all together