Warming up the neural circuits...
By the end of this chapter you will:
Before you can build a backend, you need to know what the backend is talking to — and that is the internet. The internet is not a vague cloud; it's a set of strict, ordinary rules. Once you see them, every weird bug in your career gets easier.
Imagine you live in Mumbai and want to send a message to a friend in Tokyo. You don't know any roads. You don't speak Japanese. You don't own a plane.
So you write a postcard. On the front: their name and address. On the back: your message. You drop it in a postbox. You do not deliver it yourself. You hand it to a system that has been doing this for 200 years — local post office, sorting hub, international flight, Tokyo post office, local mail carrier, friend's door.
You trusted a network of cooperating relays. Each one only knew the next hop. None of them knew the whole route. None of them needed to.
That's the internet. Your laptop is the Mumbai postbox. The website's server is your friend in Tokyo. In between are routers — postal sorting hubs — that only know "where to send this next." Your packets travel through 12–20 of them, and you never notice.
If you ever find yourself thinking the internet is magic, come back to this postcard. It's not magic. It's a very, very fast post office.
The internet has many layers. You will hear engineers throw around terms like OSI model, TCP/IP , Layer 7. Don't memorize all seven layers. As a backend dev, you really only need four:
| Layer | What it does | Examples |
|---|---|---|
| Link | Moves bits over a physical wire or radio | Ethernet, Wi-Fi |
| Network | Moves packets between machines | IP (v4 and v6) |
| Transport | Moves reliable streams between programs | TCP, UDP |
| Application | The actual app you wrote | HTTP, , SMTP |
Read that table again. The browser sits at the top. The cable in the wall sits at the bottom. Every layer adds something the layer below doesn't have.
IP delivers a single envelope. TCP turns a pile of envelopes into a guaranteed, in-order conversation. HTTP is the language of the letter inside.
You type https://api.example.com/users/42 and press Enter. Here's the full sequence, slowed down:
Rendering diagram…
Your browser doesn't know what api.example.com means. Computers only understand IP addresses (numbers like 203.0.113.42). So the first thing it does is ask: what's the IP for this hostname?
This question goes to a DNS resolver. By default, it's your ISP's resolver (or Google's 8.8.8.8, or Cloudflare's 1.1.1.1). The resolver may have the answer cached. If not, it asks the root servers, then the .com servers, then the example.com nameservers — a tree walk that usually finishes in under 50ms.
The answer comes back as an A record (IPv4) or AAAA record (IPv6).
$ dig api.example.com +short
203.0.113.42
$ dig api.example.com AAAA +short
2001:db8::42Your OS caches it. Your browser caches it. Your ISP caches it. The TTL (time-to-live) is set by the domain owner. This is why when you point a domain at a new server, your laptop may still hit the old one for hours.
Now the browser knows the server's IP. But IP alone is just "deliver this envelope." It's unreliable — the envelope can vanish, arrive twice, arrive out of order. The browser needs a reliable byte stream, so it uses TCP.
TCP opens a connection with a three-way handshake:
This handshake costs one full round-trip-time (RTT). If your server is in Singapore and your user is in Mumbai, that's roughly 60ms gone before any data flows. This is why CDNs and edge servers exist — to put a TCP endpoint geographically closer to the user.
Modern web traffic isn't sent in the clear. TLS (Transport Layer Security — the protocol behind HTTPS) wraps the TCP stream in encryption. The handshake exchanges a session key the two sides will use to encrypt everything that follows.
You will spend two chapters on TLS later. For now, three things:
203.0.113.42.NOW, finally, the browser sends the actual HTTP request:
GET /users/42 HTTP/1.1
Host: api.example.com
Accept: application/json
User-Agent: Mozilla/5.0 ...The server reads it, runs your backend code (this is where you come in!), and sends a response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 51
{"id":42,"name":"Aditi","email":"aditi@example.com"}The browser receives the bytes, parses the JSON, and your app reacts.
That's it. That is the entire web. Everything else — load balancers, caches, queues — is optimization or scale.
When TCP says "send these bytes," IP chops the bytes into packets. Each packet is independent. Each packet has:
Each packet is handed to your home router, which hands it to your ISP, which hands it to a bigger ISP, which hands it to a transit network, which hands it to the destination's ISP, which hands it to the destination router, which hands it to the server.
$ traceroute api.example.com
1 192.168.1.1 (your router) 1 ms
2 10.0.0.1 (ISP gateway) 5 ms
3 103.27.99.1 (ISP backbone) 12 ms
4 62.115.43.18 (regional transit) 24 ms
5 ... ...
12 203.0.113.42 (destination) 180 msEach row is a router. None of them know the full path. Each one looks at the destination IP, consults a routing table, and picks the next hop. If a router is down, neighbors reroute. This is why the internet doesn't crash when AWS us-east-1 has a bad day — only services hosted there go down, the network itself reroutes around.
When users report "the site is slow," 90% of the time it's not your server. It's a slow hop somewhere in the network. traceroute and mtr are your truth-tellers. Memorize them.
IP addresses come in two flavors:
192.168.1.1. Total possible: ~4.3 billion. We ran out around 2011.2001:db8::1. Total possible: ~3.4 × 10³⁸. We will not run out.For your day job: write code that handles both. Most languages and libraries do this transparently — but only if you don't hardcode the regex \d+\.\d+\.\d+\.\d+. If you store IPs in a database, use the inet type in Postgres, not varchar.
-- Wrong
last_login_ip VARCHAR(15)
-- Right (handles both IPv4 and IPv6)
last_login_ip INETTreating the network as if it never fails. The network fails constantly — packets drop, DNS times out, connections hang. Your code must assume the worst. Timeouts and retries are not optional.
| Mistake | Why it's wrong | What to do instead |
|---|---|---|
| Hardcoding an IP address | DNS lets ops change servers without redeploying. Hardcoded IPs guarantee a midnight rollback. | Use hostnames. Let DNS do its job. |
| No timeout on outbound HTTP calls | A hung connection ties up a Node event-loop slot forever. One slow third-party can take your whole service down. | Always set a connect timeout AND a read timeout. 5s is a fine default. |
| Assuming DNS lookups are free | A cold DNS lookup can take 100ms+. In a hot path, this matters. | Cache DNS in your app or use a pooled HTTP client that does it for you. |
| Storing IPs as VARCHAR | Can't filter by subnet, can't be sure the format is valid. | Use INET in Postgres or the equivalent native type in your DB. |
| Confusing "TLS encrypts the URL" | The hostname is visible (SNI). Only the path and headers are encrypted. | Don't put secrets in the hostname. |
Production. Every long-lived service should track its outbound network failures. Add a metric for dns_lookup_failures_total and tcp_connect_failures_total. When they spike, it's not your code — it's the network.
Performance. RTT is the silent killer. A page that does 30 sequential API calls to a server 200ms away takes 6 seconds before the server even thinks. Either reduce the number of calls, move them closer (/edge), or parallelize them.
Security. The IP your server sees is not necessarily the user's. If you sit behind a or proxy, the client's real IP is in X-Forwarded-For or Forwarded. Validate the proxy chain before trusting it — anyone can claim any IP in a header.
// Express — only trust the immediate reverse proxy
app.set('trust proxy', 'loopback')
// or for cloud LBs:
app.set('trust proxy', 1)dig (or nslookup) on google.com. How many IPs come back? Why?traceroute github.com. Count the hops. Identify which ones are inside your country.203.0.113.42. Watch the TTL countdown.curl --resolve, force a request to a specific IP while keeping the Host header. Why is this useful when testing a server before flipping DNS?Beginner. Explain what happens when you type google.com and press Enter. (This is the most-asked interview question in tech. Practice it cold.)
Beginner. What is the difference between TCP and UDP? Answer: TCP guarantees ordered, reliable delivery (handshake, retransmits). UDP is fire-and-forget — faster, no guarantees. Used for DNS, video streaming, games.
Senior. How would you reduce the latency of a service deployed in us-east for users in ap-south? Talk about edge caching for reads, regional read replicas, regional API endpoints, and the trade-offs of multi-region writes.
Senior. Walk me through what your service does when DNS for the database goes down. Good answers mention DNS caching, connection pooling, retries with backoff, circuit breakers, and falling back to a cached read-only view.
The internet is a layered system. IP delivers envelopes, TCP turns them into reliable streams, TLS encrypts those streams, and HTTP is the language inside. DNS turns names into IPs. Routers hand-off packets hop by hop. Everything you build sits on top of this — and every weird production issue eventually traces back to one of these layers.
INET better than VARCHAR(15) for storing IPs in Postgres?