Skip to content
Blog

How the Internet Works: What Happens When You Open a Website

By Published A short read

How the internet works: a laptop, a home router, the ISP, DNS and a web server joined by one path, with the measured times for DNS, TCP, TLS and HTTP

When you open a website, your computer first asks DNS to turn the name into an IP address, then opens a connection to that address, sets up encryption with TLS, and sends an HTTP request. The server's answer comes back as small packets, passed from router to router, sometimes through cables on the sea floor, and your browser puts them back together into the page. On my connection in India, getting from the name to the first bytes of this blog's page took under half a second. In this post we follow each step in order, and run real commands (nslookup, a short Python script and tracert) so you can watch every step happen on your own machine.

Key takeaways

  • DNS is the internet's phone book: it turns blog.letsbug.in into an IP address like 192.178.211.121.
  • TCP (or QUIC for HTTP/3) opens a connection; TLS encrypts it. That's the lock in your address bar.
  • HTTP is the actual conversation: the browser asks GET /, the server answers 200 OK and the page.
  • Everything travels in packets of up to about 1,500 bytes, and routers pass them hop by hop. tracert shows you the hops.
  • Between countries, most of that trip is on undersea fibre-optic cables: TeleGeography tracks more than 600 active and planned ones, and Mumbai and Chennai are India's big landing cities.

This post goes with our short How the Internet Works: A Fun Journey! The video, from December 2024, gives the big picture in under a minute. This written guide goes deeper, and every command and number in it was run and checked in October 2026.

The whole journey in one picture

Let's say you type blog.letsbug.in and press Enter. Here's everything that happens before the page appears, in order:

  1. DNS lookup: find the IP address for the name.
  2. Connect: open a TCP connection to that address (or QUIC, for HTTP/3).
  3. TLS: agree on encryption keys and check the site's certificate.
  4. HTTP: ask for the page and get it back.
  5. Packets and routers: under all of this, data moves in small packets, router to router, over copper, Wi-Fi, fibre and undersea cables.
  6. Back to your screen: the browser reads the HTML, fetches the images and styles it needs, and draws the page.
The journey of one web request as a sequence diagram: the laptop asks the DNS resolver for blog.letsbug.in and gets 192.178.211.121 (16 ms); then, through the home router and 3 Airtel hops, it does the TCP handshake with Google's web server (11 ms), the TLS handshake (81 ms) and GET / answered by 200 OK and the HTML (345 ms)
The trip we measure in this post: from my laptop to the server behind blog.letsbug.in and back.

Step 1: DNS turns a name into an address

Computers on the internet find each other by IP address, a number. People remember names. DNS, the Domain Name System, connects the two. Let's ask it ourselves. Open a terminal (Command Prompt on Windows, Terminal on Mac or Linux) and type:

nslookup blog.letsbug.in

Here's what I got:

Server:  dns.google
Address:  8.8.8.8

Non-authoritative answer:
Name:    ghs.google.com
Addresses:  2404:6800:4000:1025::79
          192.178.211.121
Aliases:  blog.letsbug.in

Three things to notice:

  • Server: dns.google is the recursive resolver my computer asked: Google Public DNS at 8.8.8.8. Yours is probably your internet provider's resolver, or 1.1.1.1 if you've set Cloudflare's.
  • Aliases: blog.letsbug.in and Name: ghs.google.com: our blog's name is an alias (a CNAME record) that points to Google's Blogger servers. Blogger's help tells every custom domain to point a CNAME at ghs.google.com.
  • Two addresses: 192.178.211.121 is an IPv4 address (four numbers), and 2404:6800:4000:1025::79 is an IPv6 address, the newer, much longer kind. Run it again later and you may get a different 192.178.x.x address: Google spreads the blog across many servers.

Who the resolver asks

If the resolver hasn't seen the name recently, it walks down the DNS tree, asking a different server at each level:

  1. A root server, which points it to the servers for .in. The root zone has 13 named root servers (a.root-servers.net to m.root-servers.net), which IANA says are really "a network of hundreds of servers in many countries".
  2. The TLD server for .in, which points it to the nameservers for letsbug.in.
  3. The authoritative nameserver for letsbug.in, which has the actual answer.

You can see the real servers at each level with -type=NS:

nslookup -type=NS in.
in      nameserver = ns1.registry.in
in      nameserver = ns2.registry.in
...

nslookup -type=NS letsbug.in
letsbug.in      nameserver = cody.ns.cloudflare.com
letsbug.in      nameserver = joselyn.ns.cloudflare.com

So India's .in registry sends the resolver to Cloudflare, which holds letsbug.in's records. Cloudflare's own guide counts 8 steps in a full lookup when nothing is cached. Most of the time something is cached: in my runs the first lookup took 34 ms and later ones 6 to 22 ms, because the answer was already saved nearby.

What an IP address is

MDN puts it nicely: a MAC address is like a fingerprint, but an IP address is a street address. It says where a computer is on the network, so routers can work out which way to send data, the same way a postal worker uses a PIN code. Your home router gives your laptop a private address (my router itself is 192.168.1.1), and your internet provider gives your router a public one.

Step 2: open a connection (TCP or QUIC)

Now our computer knows where to go. Before sending the request, it opens a connection. With TCP, that's a three-way handshake:

  1. Your computer sends SYN ("can we talk?").
  2. The server replies SYN-ACK ("yes").
  3. Your computer sends ACK ("great, starting now").

TCP also numbers the data so it arrives complete and in order, and resends anything that gets lost. HTTPS uses port 443 (plain HTTP uses port 80), like a flat number inside the building.

Newer sites can use HTTP/3, which runs on QUIC instead of TCP. QUIC is built on UDP, folds the TLS handshake into its own handshake, and copes better when a packet is lost or your phone switches from Wi-Fi to mobile data. A server tells the browser it speaks HTTP/3 with a response header. Google's home page sends one; our blog doesn't (yet), so browsers reach it over TCP:

curl -sI https://www.google.com/
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

Step 3: TLS makes it private

HTTPS is HTTP inside a TLS tunnel. In the TLS handshake, the browser and server agree on encryption keys, and the server shows a certificate that proves it really is blog.letsbug.in. Your browser checks that certificate before it sends anything private. With TLS 1.3, the current version, the handshake needs just one round trip (TLS 1.2 needed two), and when you reconnect to a site it can even send data with zero extra round trips (0-RTT).

Step 4: the HTTP request and response

Finally, the browser asks for the page. An HTTP request is plain text with a method, a path and headers:

GET / HTTP/1.1
Host: blog.letsbug.in
Connection: close

That's HTTP/1.1, which is readable text, so it's what we send in our script. Browsers usually use HTTP/2 (or HTTP/3), which carries the same requests in a compact binary form; our blog's server speaks HTTP/2.

The server answers with a status code (200 means OK, 404 means not found), its own headers, and then the body: the HTML of the page. HTTP is stateless, MDN notes: each request stands alone, which is why websites use cookies to remember that you're logged in.

Measure the whole trip with Python

Let's time each step ourselves. This script uses only Python's standard library (I ran it with Python 3.13), so there's nothing to install. Save it as journey.py:

import socket, ssl, time

HOST = "blog.letsbug.in"
ctx = ssl.create_default_context()  # load trusted certificates before timing

t0 = time.perf_counter()
ip = socket.getaddrinfo(HOST, 443, socket.AF_INET, socket.SOCK_STREAM)[0][4][0]
t1 = time.perf_counter()
sock = socket.create_connection((ip, 443), timeout=10)
t2 = time.perf_counter()
tls = ctx.wrap_socket(sock, server_hostname=HOST)
t3 = time.perf_counter()
tls.sendall(f"GET / HTTP/1.1\r\nHost: {HOST}\r\nConnection: close\r\n\r\n".encode())
data = b""
while b"\r\n\r\n" not in data:
    data += tls.recv(4096)
t4 = time.perf_counter()
version = tls.version()
tls.close()

head = data.split(b"\r\n\r\n")[0].decode("latin-1").split("\r\n")
print("1. DNS  ", HOST, "->", ip, f"({(t1 - t0) * 1000:.0f} ms)")
print("2. TCP  ", "connected to port 443", f"({(t2 - t1) * 1000:.0f} ms)")
print("3. TLS  ", version, f"({(t3 - t2) * 1000:.0f} ms)")
print("4. HTTP ", head[0], f"({(t4 - t3) * 1000:.0f} ms)")
for line in head[1:]:
    if line.lower().startswith(("content-type:", "server:")):
        print("        ", line)

Run it with python journey.py. Here's one of my runs:

1. DNS   blog.letsbug.in -> 192.178.211.121 (16 ms)
2. TCP   connected to port 443 (11 ms)
3. TLS   TLSv1.3 (81 ms)
4. HTTP  HTTP/1.1 200 OK (345 ms)
         Content-Type: text/html; charset=UTF-8
         Server: GSE

What the numbers say:

  • DNS, 16 ms: quick, because the answer was already cached nearby, so nobody had to walk the whole DNS tree.
  • TCP, 11 ms: one round trip to the server and back. That matches the 9 to 12 ms that tracert shows below.
  • TLS, 81 ms: TLS 1.3 needs only one round trip on the wire, so most of this is probably time the server spends before replying. For comparison, www.google.com finished its TLS handshake in about 16 ms in my runs.
  • HTTP, 345 ms: the longest step. Blogger builds the page before sending the first bytes. One run took over a second, so expect yours to jump around.

Add them up: 16 + 11 + 81 + 345 = 453 ms, less than half a second from name to first bytes of the page. Server: GSE is the name Google's server reports, and Content-Type: text/html tells the browser the body is a web page.

Packets and routers: see every hop with tracert

The page doesn't travel as one big piece. It's cut into packets, small chunks that are put back together at the other end. On most networks a packet can carry at most about 1,500 bytes (the usual MTU, the largest packet a link accepts), so a 300 KB page needs at least 200 packets. Each packet has the destination IP address on it, and each router along the way reads it and passes the packet to the next router that's closer.

On Windows, tracert shows those routers. (On Mac and Linux it's traceroute.) Here's my trace to our blog. The -d flag skips name lookups so it runs faster:

tracert -d blog.letsbug.in

Tracing route to ghs.google.com [192.178.211.121]
over a maximum of 30 hops:

  1    14 ms    29 ms     7 ms  192.168.1.1
  2    14 ms     8 ms    12 ms  110.226.15.255
  3    10 ms    10 ms     5 ms  125.20.27.9
  4     9 ms    15 ms    11 ms  116.119.57.26
  5    12 ms    11 ms     9 ms  192.178.211.121

Trace complete.
  • Each hop is tried three times, so you get three times per line.
  • Hop 1 is my home router (a private 192.168 address).
  • Hops 2 to 4 are my internet provider's routers. The public registry, APNIC, lists all three as Bharti networks (one record names Bharti Airtel Limited).
  • Hop 5 is Google's server. Airtel hands our packets straight to Google's network, and the round trip is only about 10 ms, so the server is close by.

How does tracert find the routers? Every packet carries a TTL (time to live) number, and each router lowers it by 1. When it hits 0, that router drops the packet and sends back a "time exceeded" message. tracert sends packets with TTL 1, then 2, then 3, and each reply reveals the next router. Microsoft's documentation notes that some routers don't send these replies. Their line shows * stars and "Request timed out", but your traffic still goes through them.

One more piece of physics. Light in glass fibre travels at about 200,000 km per second, two-thirds of its speed in a vacuum, because glass slows it down (its refractive index is about 1.5). That's 200 km per millisecond. A 10 ms round trip is 5 ms each way, so this server is at most about 1,000 km of cable away, and likely much closer, since routers add delay too.

Servers and data centres

The "server" that answered is one computer among thousands in a data centre, a building full of servers with fast links, backup power and cooling. Big sites don't keep just one copy of a page: a CDN (content delivery network), in Cloudflare's words, is "a geographically distributed group of servers" that caches content closer to users. That's why a site run from the US can still answer in India in a few milliseconds.

Undersea cables: how the internet crosses oceans

When the server is overseas, the packets almost always cross the sea on a submarine cable, not a satellite. TeleGeography, which maps them, says:

  • As of 2026 it tracks more than 600 active and planned submarine cables, and as of early 2026 there are over 1.5 million km of them in service.
  • In the deep ocean a cable is about as wide as a garden hose, and the glass fibres inside carrying the light are roughly the width of a human hair. Near the shore the cables are buried under the seabed.
  • Cables break about 200 times a year (data from the International Cable Protection Committee), two-thirds of the time from fishing boats and dragged anchors. You rarely notice because traffic is spread across many cables.

India's landing points. In TeleGeography's Submarine Cable Map data (fetched 10 October 2026), 23 cables land in India: 18 in service and 5 planned. Mumbai is the busiest, with 16 (12 in service, including 2Africa, SeaMeWe-4, AAE-1 and IMEWE), and Chennai has 10 (7 in service, including Bay of Bengal Gateway, i2i and the Chennai-Andaman & Nicobar Islands cable). So when you open a site hosted in Europe, your packets most likely leave India from a landing station in Mumbai.

Back to your screen

The first HTML that arrives is only the start. MDN describes a web page as "constructed from resources such as text content, layout instructions, images, videos, scripts". So the browser reads the HTML, finds the CSS, JavaScript and images it mentions, and fetches each one. Files from the same site reuse the open connection and the cached DNS answer, so they're much faster than the first; files from other hosts (our images come from media.letsbug.in) need their own lookup and connection. As the pieces land, it lays out the page and paints it on your screen.

What each layer does

Network engineers group these jobs into layers. Each one only talks to the layer above and below it, which is why your browser doesn't care whether you're on Wi-Fi or mobile data.

What each internet layer does: application (HTTP and DNS, what to say), security (TLS, keep it private), transport (TCP or QUIC, deliver it complete and in order), internet (IP and routers, find the way) and link (Wi-Fi, Ethernet and fibre, move bits to the next device)
LayerExamplesIts jobSee it with
ApplicationHTTP, DNSWhat to say: "GET /", "what's the address?"nslookup, curl -I
SecurityTLSKeep it private and prove who the server isThe lock icon, tls.version()
TransportTCP, QUIC (on UDP)Deliver it complete and in orderThe TCP time in journey.py
InternetIP, routersFind the way, hop by hoptracert
LinkWi-Fi, Ethernet, fibreMove the bits to the next deviceYour router's lights

For exams you'll see this as the 4-layer TCP/IP model or the 7-layer OSI model. Our network models questions and answers compare them. TLS isn't a layer of its own in those textbook models: it sits between transport and application.

Common errors and what they mean

Each step can fail in its own way, and the error message tells you which step broke. These are the real messages from Windows and Python 3.13:

  • DNS failed. nslookup says *** dns.google can't find nosuchname.letsbug.in: Non-existent domain, and Python raises socket.gaierror: [Errno 11001] getaddrinfo failed (on Linux the number and wording differ). Check the spelling, then your network. If only one network fails, try another DNS resolver.
  • Connection failed. TimeoutError: timed out means no reply came back at all: you're offline, a firewall blocks the port, or the server is down. On a web page you can detect this with JavaScript, see detect online or offline status in JavaScript.
  • TLS failed. ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired, or Hostname mismatch, certificate is not valid for 'wrong.host.badssl.com'. The connection worked, but the certificate didn't prove who the server is. Also check your computer's date: a wrong clock makes valid certificates look expired.
  • HTTP failed. urllib.error.HTTPError: HTTP Error 404: Not Found. Everything worked up to the server, which simply has no page at that path. A 5xx code (like 500 or 503) means the server itself had a problem.

Try these on your own machine. (1) Run python journey.py twice in a row. Which number drops the second time, and why? (2) In my trace, light needed about 10 ms for the round trip. If a server in Europe answers in 150 ms, what's the most fibre the packets could have crossed one way?

Show the answers

(1) DNS usually drops (from 34 ms to as low as 6 ms in my runs), because the answer is now cached by your computer or resolver.
(2) 150 ms round trip is 75 ms each way, and light in fibre covers about 200 km per ms: 75 × 200 = 15,000 km at most. The real cable path is shorter, because routers and servers add delay too.

Questions people ask

What happens when you type a URL in the browser?

The browser looks up the domain's IP address with DNS, opens a TCP or QUIC connection to it, sets up encryption with TLS, and sends an HTTP request. The server sends back the HTML in packets that routers carry hop by hop. The browser then fetches the CSS, scripts and images the page needs and draws it.

Is the internet the same as the World Wide Web?

No. The internet is the network itself: cables, routers and the IP addresses that connect computers. The Web is one thing that runs on it: pages and links fetched with HTTP. Email, online games and video calls use the internet too, without being the Web.

Does the internet go through satellites or cables?

Mostly cables. Between countries, traffic travels on undersea fibre-optic cables; TeleGeography tracks more than 600 active and planned ones. In TeleGeography's words, satellites "do an excellent job of reaching areas that aren't yet wired with fiber", but the cables carry the bulk of it.

What is the difference between HTTP and HTTPS?

HTTPS is HTTP sent inside an encrypted TLS connection. Nobody between you and the server, like the café Wi-Fi or your ISP, can read or change the contents (they can still see which site's IP address you connect to), and the certificate proves you're talking to the real site. HTTPS uses port 443; plain HTTP uses port 80.

Why is a website slow sometimes?

Any step can be the slow one. DNS can be slow on the first lookup, a far-away server adds round-trip time, a busy server takes longer to build the page, and a weak Wi-Fi signal loses packets that must be resent. Run journey.py to see which step takes longest.

Keep going

Sources

All pages fetched 10 October 2026.

Every command and code sample in this post was run on Windows 11 with Python 3.13 on 10 October 2026, and every number was checked by a script before publishing. Your addresses and times will differ: that's the point, so run them yourself.