 Command

Pranesh Nikhar's personal site. Vim-style keybinds for navigation; theme + font pickers below.

Theme
 Font Body Code
Reader
Keybinds
Navigation
j / ↓ Next item k / ↑ Previous item g First item in region G Last item in region zz Center focused item h / l Move left/right region ] / [ Next/previous heading } / { Next/previous block d / u Half-page down/up
Layout
<zh> / <zl> Toggle left/right sidebar <zr> Toggle reader view <zj> / <zk> Focus main/navbar <S-h/j/k/l> Focus left/main/navbar/right ⌃H / ⌃L Focus left/right sidebar ⌃J / ⌃K Focus main/navbar ⇧C / ⇧E Collapse / expand all sections
Dialogs
⌃P / : Command palette ⌃X Theme picker / Search ? Show keybinds Esc / ⌃C Close dialog
History
n Next document b Previous document ⌃O History back ⌃I History forward
 Search
about: Pranesh Nikhar about/more: πŸͺͺ More docs/test: Docs Test ideas: πŸ’‘ Ideas more: βž• More now: Now posts: πŸ“¬ Posts projects: πŸ“š Projects webtui: Style posts/agentic-eda: πŸ“Š AgenticEDA β€” Automated Exploratory Data Analysis with LangGraph posts/cap-theorem-outage-story: 🌐 CAP Theorem with a Real Outage Story posts/codepilot: ✈️ CodePilot β€” From Requirements to Deployable FastAPI Backend posts/common-auth-mistakes: πŸ” Common Auth Mistakes Developers Make posts/compiled-vs-jit-vs-interpreted: ⚑ Why Is X Language Fast or Slow? β€” Compiled vs JIT vs Interpreted posts/cs-degree-gaps: πŸŽ“ Things CS Degrees Don't Teach You posts/cve-2025-breach-analysis: πŸ›‘οΈ CVE-2025 Breach Analysis β€” Midnight Blizzard and the 16 Billion Credential Leak posts/fixloop: πŸ”„ FixLoop β€” AI Agent Loop for Self-Correcting Code posts/functional-vs-oop: ⚑ Functional vs OOP β€” Same Problem, Both Ways posts/getman: 🦾 Getman β€” Declarative API Tester for CLI & TUI posts/how-compilers-optimize: βš™οΈ How Compilers Actually Optimize Your Code posts/http3-quic: ⚑ HTTP/3 and QUIC β€” Why They Matter posts/leetcode-vs-engineering: 🧩 LeetCode vs Real Engineering Skills posts/llm-from-scratch: 🧠 LLM from Scratch β€” GPT-Style Transformer in PyTorch posts/lsm-trees-bloom-filters: 🌳 LSM Trees & Bloom Filters β€” Production Deep Dive posts/mcp-workflow-builder: πŸ”§ MCP Workflow Builder β€” Visual DAG for MCP Tools posts/persistent-memory: 🧠 Persistent Memory β€” Long-Term Memory for AI Agents via MCP posts/playcli: 🎬 PlayCLI β€” Terminal Video Player posts/postgres-mvcc: πŸ—„οΈ How PostgreSQL MVCC Works β€” Multi-Version Concurrency Control Deep Dive posts/raft-consensus: β›΅ Raft Consensus Algorithm Explained posts/rust-borrow-checker: πŸ¦€ Rust Borrow Checker β€” Catches Real Bugs posts/titan: πŸ€– Titan β€” Terminal AI Coding Agent posts/what-happens-url: 🌐 What Happens Between Typing a URL and Seeing the Page posts/what-happens-when-you-run-a-program: βš™οΈ What Actually Happens When You Run a Program posts/zero-knowledge-proofs: πŸ” Zero-Knowledge Proofs Explained Simply webtui/components/accordion: Accordion webtui/components/badge: Badge webtui/components/button: Button webtui/components/checkbox: Checkbox webtui/components/dialog: Dialog webtui/components/input: Input webtui/components/popover: Popover webtui/components/pre: Pre webtui/components/progress: Progress webtui/components/radio: Radio webtui/components/range: Range webtui/components/separator: Separator webtui/components/spinner: Spinner webtui/components/switch: Switch webtui/components/table: Table webtui/components/textarea: Textarea webtui/components/tooltip: Popover webtui/components/typography: Typography webtui/components/view: View webtui/contributing/contributing: Contributing webtui/contributing/contributing: ## Local Development webtui/contributing/contributing: ## Issues webtui/contributing/contributing: ## Pull Requests webtui/contributing/style-guide: Style Guide webtui/contributing/style-guide: ## CSS Units webtui/contributing/style-guide: ## Selectors webtui/contributing/style-guide: ## Documentation webtui/installation/astro: Astro webtui/installation/astro: ## Scoping webtui/installation/astro: ### Frontmatter Imports webtui/installation/astro: ### β€Ήstyleβ€Ί tag webtui/installation/astro: ### Full Library Import webtui/installation/nextjs: Next.js webtui/installation/vite: Vite webtui/plugins/plugin-dev: Developing Plugins webtui/plugins/plugin-dev: ### Style Layers webtui/plugins/plugin-nf: Nerd Font Plugin webtui/plugins/theme-catppuccin: Catppuccin Theme webtui/plugins/theme-custom: Custom Theme webtui/plugins/theme-everforest: Everforest Theme webtui/plugins/theme-gruvbox: Gruvbox Theme webtui/plugins/theme-nord: Nord Theme webtui/plugins/theme-vitesse: Vitesse Theme webtui/start/ascii-boxes: ASCII Boxes webtui/start/changelog: Changelog webtui/start/installation: Installation webtui/start/installation: ## Installation webtui/start/installation: ## Using CSS webtui/start/installation: ## Using ESM webtui/start/installation: ## Using a CDN webtui/start/installation: ## Full Library Import webtui/start/installation: ### CSS webtui/start/installation: ### ESM webtui/start/installation: ### CDN webtui/start/intro: Introduction webtui/start/intro: ## Features webtui/start/plugins: Plugins webtui/start/plugins: ## Official Plugins webtui/start/plugins: ### Themes webtui/start/plugins: ## Community Plugins webtui/start/theming: Theming webtui/start/theming: ## CSS Variables webtui/start/theming: ### Font Styles webtui/start/theming: ### Colors webtui/start/theming: ### Light & Dark webtui/start/theming: ## Theme Plugins webtui/start/theming: ### Using Multiple Theme Accents webtui/start/tuis-vs-guis: TUIs vs GUIs webtui/start/tuis-vs-guis: ## Monospace Fonts webtui/start/tuis-vs-guis: ## Character Cells
 Theme Current: Light j/k or ↑/↓ + Enter

🌐 What Happens Between Typing a URL and Seeing the Page

A deep dive into the journey of a single URL β€” URL parsing, DNS resolution, TCP/TLS handshakes, HTTP requests, server processing, and browser rendering β€” with a full timing breakdown.

🎯 The Question Every Interviewer Loves

β€œWhat happens when you type https://example.com into your browser and press Enter?”

This question endures because it touches every layer of the networking stack β€” application, transport, network, link, and physical. A complete answer touches on 8 distinct phases. Here they are, from keystroke to pixels.


1️⃣ URL Parsing and HSTS Check

Before anything leaves your machine, the browser parses the URL into its components:

ComponentValue
Protocolhttps
Hostnameexample.com
Port443 (implied by HTTPS)
Path/ (default)
Fragmentnone

The browser then checks its HSTS (HTTP Strict Transport Security) preload list. If the domain is found, the browser refuses to make an insecure HTTP connection β€” it upgrades directly to HTTPS. This prevents SSL-stripping attacks even on the first request.

If the domain is not preloaded, the browser sends a plain HTTP request first and relies on the server’s Strict-Transport-Security response header to remember the upgrade for future visits.


2️⃣ DNS Resolution

The browser needs the server’s IP address. It checks a chain of caches:

Browser cache β†’ OS cache β†’ Router cache β†’ ISP DNS β†’ Recursive resolver

If none of the caches have the mapping, the recursive resolver (usually your ISP’s or Cloudflare’s 1.1.1.1) begins the lookup:

  1. Root nameserver β€” tells the resolver where the .com TLD nameservers are
  2. TLD nameserver β€” tells the resolver where example.com’s authoritative nameservers are
  3. Authoritative nameserver β€” returns the actual A (IPv4) or AAAA (IPv6) record
Browser          Resolver         Root (.com)    TLD Authoritative
  β”‚                  β”‚               β”‚            β”‚
  │── query: ──────► β”‚               β”‚            β”‚
  β”‚  example.com     │── where's ──► β”‚            β”‚
  β”‚                  β”‚   .com?       β”‚            β”‚
  β”‚                  │◄── go ask ────│            β”‚
  β”‚                  β”‚   TLD β†’      β”‚            β”‚
  β”‚                  │── where's ──────────────► β”‚
  β”‚                  β”‚   example?   β”‚            β”‚
  β”‚                  │◄────────── 93.184.216.34 ─│
  │◄── 93.184.216.34─│               β”‚            β”‚

Typical timing: 20–50ms for a cold cache, <1ms for a warm cache.

πŸ”§ Modern DNS Optimizations

  • DNS prefetching: Browsers eagerly resolve domain names found in <a> tags before the user clicks
  • DNS-over-HTTPS (DoH): Encrypts DNS queries to prevent snooping (used by Firefox, Chrome)
  • DNS-over-TLS (DoT): Alternative encrypted DNS, preferred by Android

3️⃣ TCP Handshake

With the IP address known, the browser opens a TCP connection to port 443. TCP provides reliable, ordered delivery over an unreliable IP network. The three-way handshake establishes a connection:

Client                      Server
  β”‚                           β”‚
  │────── SYN ──────────────► β”‚  Client: "Hey, let's talk"
  β”‚                           β”‚
  │◄───── SYN-ACK ────────── β”‚  Server: "OK, I'm ready. You?"
  β”‚                           β”‚
  │────── ACK ──────────────► β”‚  Client: "Confirmed."
  β”‚                           β”‚

Each unacknowledged segment triggers a retransmission, and the round-trip time (RTT) determines the minimum latency. On a 30ms RTT connection, the TCP handshake alone takes 60ms (one round trip for SYN β†’ SYN-ACK, then ACK is the second).

TCP Fast Open (TFO) eliminates this on repeat connections by sending data inside the SYN packet, saving one RTT. Adoption is limited (~10% of servers).


4️⃣ TLS 1.3 Handshake

Plain TCP gets you a raw pipe, but you need encryption. TLS 1.3 (RFC 8446) reduced the handshake from 2 RTTs (TLS 1.2) to 1 RTT for fresh connections and 0 RTT for resumed ones.

Client                      Server
  β”‚                           β”‚
  │── ClientHello ──────────► β”‚  Key share, supported ciphers, random nonce
  β”‚   (public key share)     β”‚
  β”‚                           β”‚
  │◄── ServerHello ──────────│  Cipher choice, server cert + signature
  β”‚    + Cert + Finished     β”‚
  β”‚                           β”‚
  │── Finished ─────────────►│  Client verifies cert, sends Finished
  β”‚                           β”‚
  │◄════ Encrypted Data ═══► β”‚  Application data begins immediately

Certificate Verification

The browser checks:

  1. Certificate chain β€” Is the cert signed by a trusted CA?
  2. Hostname match β€” Does the cert’s Common Name or SAN match example.com?
  3. Expiry β€” Is the cert still valid?
  4. Revocation β€” Is the cert revoked? (via OCSP stapling, not CRL β€” OCSP is faster)

Typical timing: 1–2 RTT + certificate validation (~50–200ms total). With TLS 1.3 0-RTT resumption, returning visitors skip the handshake entirely.


5️⃣ HTTP Request

With a secure channel established, the browser sends an HTTP request:

GET / HTTP/1.1
Host: example.com
Accept: text/html,application/xhtml+xml,...
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

HTTP/1.1 vs HTTP/2 vs HTTP/3

FeatureHTTP/1.1HTTP/2HTTP/3
TransportTCPTCPQUIC (UDP)
Multiplexing❌ (6 connections)βœ… (streams)βœ… (streams)
HOL blockingRequest-levelTCP-level❌ None
Header compression❌HPACKQPACK
Server pushβŒβœ…βœ…
Connection migrationβŒβŒβœ…
0-RTTβŒβŒβœ…

HTTP/1.1: One request per connection, limited to ~6 parallel connections per domain. Head-of-line blocking means one slow response blocks everything behind it.

HTTP/2: Multiplexes multiple streams over a single TCP connection. But TCP-level HOL blocking remains β€” if a single TCP packet is lost, all streams wait for the retransmission.

HTTP/3: Built on QUIC (RFC 9000), which runs over UDP. Each stream is truly independent. A lost packet only blocks its own stream. Connection migration lets you switch from Wi-Fi to cellular without dropping the connection.

Adoption as of mid-2026: HTTP/2 ~65%, HTTP/3 ~35%, HTTP/1.1 ~5% (mostly legacy).


6️⃣ Server Processing

The request arrives at the server. In a modern architecture, it passes through multiple layers:

  Client
    β”‚
    β–Ό
  CDN (Cloudflare / Fastly / Akamai)
    β”‚  β”Œβ”€ Cached static assets served here
    β–Ό
  Load Balancer (Nginx / HAProxy / AWS ALB)
    β”‚  β”Œβ”€ TLS termination, routing, health checks
    β–Ό
  Application Server (Nginx + uWSGI / Node.js / FastAPI)
    β”‚  β”Œβ”€ Session middleware, auth, business logic
    β–Ό
  Application Code
    β”‚  β”Œβ”€ Template rendering, API calls, auth checks
    β–Ό
  Database (PostgreSQL / Redis / Memcached)
    β”‚  β”Œβ”€ Query execution, cache lookup
    β–Ό
  Response (the other way back)

CDN Caching

If the CDN has a cached copy of the response (common for static assets like CSS, JS, images), the request never reaches the origin server. CDN cache hits typically take 5–20ms; cache misses add 200–500ms for origin processing.

Server-Side Timing Breakdown

PhaseTypical Time
TLS termination (LB)1–5ms
Request routing0.1–1ms
Auth/session lookup5–20ms
Application logic20–200ms
Database queries5–100ms
Response serialization1–10ms
Total server time50–500ms

7️⃣ Parsing HTML, CSS, and JavaScript

The browser receives the response β€” typically an HTML document. Parsing begins immediately, even before the full response arrives (streaming parser).

Bytes β†’ Characters β†’ Tokens β†’ Nodes β†’ DOM Tree

The Parse Pipeline

  1. HTML parsing β€” Converts bytes to DOM nodes. When the parser encounters <script> tags (without async or defer), parsing blocks until the script is fetched and executed.
  2. CSS parsing β€” CSS is render-blocking. The browser won’t render anything until the CSSOM is built. Inline CSS is free; external stylesheets block the first paint.
  3. JavaScript execution β€” JS can modify the DOM (via document.write) and the CSSOM (via CSSStyleSheet), so the parser must wait.

Preload Scanner

Modern browsers deploy a preload scanner β€” a secondary parser that skims the raw bytes for resource URLs (images, scripts, stylesheets, fonts) and kicks off fetches in parallel before the main parser reaches them. This is why putting <link rel="preload"> or <link rel="preconnect"> in the <head> can dramatically improve load times.


8️⃣ Rendering: DOM β†’ CSSOM β†’ Render Tree β†’ Layout β†’ Paint β†’ Compositing

This is where the page actually appears on screen. The rendering pipeline runs in the browser’s main thread (the β€œcritical rendering path”):

Input: DOM Tree + CSSOM
  β”‚
  β–Ό
1. Render Tree Construction
  β”‚  β”Œβ”€ Combine DOM + CSSOM
  β”‚  └─ Include only visible elements (no display:none)
  β–Ό
2. Layout (Reflow)
  β”‚  β”Œβ”€ Calculate geometry: position, width, height
  β”‚  └─ Every element's box model is computed
  β–Ό
3. Paint (Rasterization)
  β”‚  β”Œβ”€ Fill pixels: colors, borders, shadows, text
  β”‚  └─ Layers are painted independently
  β–Ό
4. Compositing
  β”‚  β”Œβ”€ Combine painted layers into final image
  β”‚  └─ GPU-accelerated via compositor thread
  β–Ό
Output: Screen pixels

Layout Thrashing

Every time you read a layout property (offsetHeight, getBoundingClientRect()) and then write a style change in the same frame, the browser must recalculate layout synchronously. This is called β€œlayout thrashing” and is a common cause of jank.

// Bad β€” forces synchronous layout twice
const height = element.offsetHeight;
element.style.height = `${height + 10}px`;
element.style.width = `${element.offsetWidth + 10}px`;

// Good β€” batch reads then writes
const height = element.offsetHeight;
const width = element.offsetWidth;
element.style.height = `${height + 10}px`;
element.style.width = `${width + 10}px`;

Compositor-Only Properties

Modern browsers can animate transform and opacity entirely on the compositor thread, bypassing layout and paint entirely. This is why will-change: transform is the go-to performance hint for animations.


πŸ“Š Full Timing Breakdown

Here’s where the milliseconds go for a typical page load with a cold cache:

PhaseTypical Time% of Total
DNS resolution20–50ms2–5%
TCP handshake30–100ms (1 RTT)3–10%
TLS 1.3 handshake30–100ms (1 RTT)3–10%
HTTP request (latency)30–100ms (1 RTT)3–10%
Server processing100–500ms15–50%
HTML parsing + CSSOM50–200ms5–20%
Render tree + layout30–100ms3–10%
Paint + composite16–50ms2–5%
Total500ms–2s100%

With a warm cache (repeat visit, CDN cache hit, TLS 0-RTT), the same page loads in 100–400ms.


πŸ’‘ Key Takeaways

  1. DNS is the hidden bottleneck β€” a cold DNS lookup can add 50+ms that most users notice
  2. TLS 1.3 is a huge win β€” 1 RTT instead of 2, plus 0-RTT for repeat visitors
  3. HTTP/3 eliminates HOL blocking β€” UDP + QUIC means one lost packet doesn’t stall everything
  4. CDNs matter more than you think β€” moving content geographically closer to users cuts latency by 50–200ms
  5. The render pipeline is fragile β€” layout thrashing from bad JS can undo all the network gains
  6. Every millisecond counts β€” Amazon found that every 100ms of latency costs 1% in revenue

The beauty of this question is that there’s always more depth. You can drill into congestion control, into the V8 parser, into the GPU compositor. The layers keep unfolding.


πŸ“– Series Navigation

 praneshnikhar.site / posts / what-happens-url Β· Top 1:1