 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

⚡ HTTP/3 and QUIC — Why They Matter

Why QUIC and HTTP/3 represent the biggest shift in web transport since HTTP/1.0 — solving head-of-line blocking, enabling connection migration, and cutting handshake overhead to zero.

🎯 The Problem with HTTP

For 25 years, HTTP ran over TCP. TCP is a marvel of engineering — reliable, ordered delivery, congestion control, flow control — but it was designed for a different era. The web of 2026 is mobile-first, latency-sensitive, and connection-unstable. TCP’s guarantees are increasingly liabilities.


1️⃣ HTTP/1.1: The Original Sin

HTTP/1.1 (RFC 2616, 1999) allowed persistent connections (Connection: keep-alive) but strictly serialized requests:

Connection 1: [ REQ 1 ]────[ WAIT ]────[ RESP 1 ]───[ REQ 2 ]───[ RESP 2 ]
Connection 2: [ REQ 1 ]────[ WAIT ]────[ RESP 1 ]───[ REQ 2 ]───[ RESP 2 ]

Problems

  • Head-of-line (HOL) blocking: A single slow response blocks all subsequent requests on that connection
  • Connection proliferation: Browsers open 6+ parallel connections per domain to work around HOL blocking, each with its own TCP and TLS handshake
  • Verbose headers: Headers are sent uncompressed every time, often exceeding the payload size for API calls
# ~400 bytes of headers for a 50-byte API response
GET /api/user HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Cookie: session=abc123; csrf=xyz789

2️⃣ HTTP/2: The Partial Fix

HTTP/2 (RFC 7540, 2015) introduced multiplexing — multiple concurrent streams over a single TCP connection:

Connection: [ REQ 1 │ REQ 2 │ REQ 3 ]───[ RESP 1 │ RESP 2 │ RESP 3 ]
FeatureWhat It Solved
MultiplexingMultiple requests in parallel on one connection
HPACK compressionHeader sizes reduced 85–90%
Server pushServer sends resources before client asks
Binary framingMore efficient than text-based HTTP/1.1
Stream priorityBrowser can hint which resources matter most

But TCP HOL Blocking Remained

This is the critical failure. HTTP/2 multiplexes streams over a single TCP connection. TCP guarantees in-order delivery. If one TCP packet is lost:

Connection: [ STREAM 1 ]│[ STREAM 2 (lost!) ]│[ STREAM 3 ]
                │               │                    │
                ▼               ▼                    ▼
           Waiting...     RETRANSMIT            Waiting...

All streams behind the lost packet are blocked — even though Stream 1 and Stream 3 have nothing to do with the lost packet. On a 1% packet loss network (typical for cellular), this kills performance.

“HTTP/2 moved HOL blocking from the request layer to the transport layer, but it didn’t eliminate it.”


3️⃣ QUIC: A New Transport (RFC 9000)

QUIC (Quick UDP Internet Connections) was originally designed by Google in 2012, deployed experimentally in Chrome in 2013, and standardized as RFC 9000 in May 2021. It’s a full transport protocol built on UDP.

Design Principles

PrincipleWhy
Encrypted by defaultTLS 1.3 is baked in, not bolted on
User-space implementationCan evolve faster than TCP (which lives in kernels)
Connection migrationSurvive network changes without reconnecting
0-RTT handshakeRepeat connections skip the handshake
Stream independenceOne lost packet ≠ all streams blocked

4️⃣ Architecture: How QUIC Works

The QUIC Packet

┌─────────────────────────────────────────────────┐
│                UDP Header (8 bytes)              │
├─────────────────────────────────────────────────┤
│              QUIC Header (variable)              │
│  Connection ID │ Packet Number │ Version │ Flags │
├─────────────────────────────────────────────────┤
│             QUIC Frame(s) (variable)             │
│  Stream ID │ Offset │ Length │ Payload │ ...     │
├─────────────────────────────────────────────────┤
│            Authentication Tag (16 bytes)         │
└─────────────────────────────────────────────────┘

Every QUIC packet is authenticated and encrypted, except the connection ID (which is needed for routing).

Stream Multiplexing Without HOL Blocking

QUIC’s key innovation is independent streams within a single connection:

Connection:
  Stream 1: [ DATA 1 ][ DATA 2 ]✓✓✓✓✓✓✓✓✓✓✓✓✓✓
  Stream 2: [ DATA 1 ][ DATA 2 (LOST!) ][ DATA 3 ]  ← only this stream blocks
  Stream 3: [ DATA 1 ][ DATA 2 ]✓✓✓✓✓✓✓✓✓✓✓✓✓✓

When Stream 2 loses a packet, only Stream 2 waits for the retransmission. Streams 1 and 3 continue delivering data. On cellular networks with 2–5% packet loss, this is transformative.

Connection Migration

This is perhaps the most underrated feature. With TCP, if you switch from Wi-Fi to cellular, every TCP connection must be re-established (new TCP handshake + new TLS handshake = 2+ RTTs lost, plus all in-flight data is dropped).

QUIC uses a Connection ID that stays stable even as the IP address changes:

   Client (Wi-Fi)                    Server
   192.168.1.5:443                   example.com
      │                                  │
      │───────────── data ──────────────►│
      │◄──────────── data ──────────────│
      │                                  │
   [Switch to cellular]
      │                                  │
   Client (LTE)                          │
   10.0.0.5:443                          │
      │                                  │
      │───────── data (same CID) ───────►│  ← No handshake!
      │◄──────── data (same CID) ───────│     Connection survives.

The server sees the same Connection ID from a new IP and continues the connection. No re-handshake. No dropped packets. Mobile apps love this.


5️⃣ HTTP/3: HTTP Over QUIC

HTTP/3 (RFC 9114) maps the HTTP semantics onto QUIC’s stream abstraction:

┌─────────────────────────────────────────┐
│              HTTP/3 Layer               │
│  ┌───────────────────────────────────┐  │
│  │ Control Stream (settings, priority)│  │
│  ├───────────────────────────────────┤  │
│  │ QPACK Stream (header table updates)│  │
│  ├───────────────────────────────────┤  │
│  │ Request Stream 1 │  Request Stream 2│  │
│  │ Response Stream 1│ Response Stream 2│  │
│  └───────────────────────────────────┘  │
├─────────────────────────────────────────┤
│              QUIC Layer                 │
│  ┌───────────────────────────────────┐  │
│  │ Stream 0 │ Stream 1 │ Stream 2 ...│  │
│  └───────────────────────────────────┘  │
├─────────────────────────────────────────┤
│              UDP Layer                  │
└─────────────────────────────────────────┘

QPACK Compression

HPACK (HTTP/2) relies on ordered delivery of header table updates, which QUIC’s independent streams break. QPACK (RFC 9204) solves this by using a dedicated encoder stream and decoder stream alongside the request streams, with a reference-counting mechanism.


6️⃣ Performance Gains

Handshake Comparison

ScenarioTCP + TLS 1.2TCP + TLS 1.3QUIC (fresh)QUIC (0-RTT)
RTTs to data3210
Time @ 30ms RTT90ms60ms30ms0ms
Time @ 100ms RTT300ms200ms100ms0ms

Packet Loss Impact

Simulated on a 30ms RTT connection with 2% packet loss:

MetricHTTP/2 (TCP)HTTP/3 (QUIC)
P50 load time1,200ms780ms
P95 load time4,500ms1,900ms
Improvement35–58% faster

Data from Google’s QUIC deployment (2015–2020) showed YouTube buffering reduced by 9% and Google Search latency reduced by 8% on desktop, 13% on mobile.


7️⃣ Congestion Control and Loss Detection

QUIC’s congestion control is more flexible than TCP’s because it lives in user space (can be updated without kernel patches).

NewReno, Cubic, BBR, and Beyond

QUIC doesn’t mandate a specific congestion control algorithm. Common choices:

AlgorithmBehaviorBest For
NewRenoClassic AIMDLow-latency networks
CubicTCP-friendly, HystartHigh-BDP networks
BBRModel-based (not loss-based)Lossy networks, variable throughput

Monotonic Timestamps

TCP uses the kernel’s jiffies for RTT estimation, which can wrap around and lose precision. QUIC uses monotonic timestamps (millisecond precision) for:

  • RTT estimation: Every packet carries a timestamp
  • ACK frequency: Receiver can delay ACKs (up to the max_ack_delay transport parameter) to reduce overhead
  • Loss detection: Default threshold is max(1.625 × RTT, 125ms) — a lost packet is declared after this time without acknowledgment

ACKs

QUIC ACKs are more expressive than TCP Selective ACKs (SACK):

QUIC ACK Frame:
  Largest Acknowledged: 142
  ACK Delay: 12ms
  ACK Range Count: 3
  First ACK Range: 20    (acknowledges 122–142)
  Additional ACK Ranges:
    [60, 80]             (acknowledges 60–80, skipped 81–121)
    [10, 20]             (acknowledges 10–20, skipped 21–59)

This tells the sender exactly which packets are missing, enabling precise retransmission without ambiguity.


8️⃣ Adoption (2026 Status)

CategoryNumbers
Global web traffic~35% over HTTP/3
Chrome support✅ Since 2020 (v87)
Firefox support✅ Since 2021 (v88)
Safari support✅ Since 2020 (v14)
Edge support✅ Since 2020 (v87)
CDN supportCloudflare, Fastly, Akamai, AWS CloudFront all support
OS supportLinux kernel 5.3+ (2020), Windows 11+, macOS 12+

Why Not 100%?

  1. Middleboxes: Corporate proxies, firewalls, and load balancers that don’t speak QUIC
  2. UDP throttling: Some networks rate-limit or block UDP (especially public Wi-Fi)
  3. Kernel support: QUIC libraries exist (quiche, lsquic, msquic, quinn), but many servers still run TCP-based stacks
  4. HTTP/2 is “good enough”: For low-loss, low-latency connections, the marginal benefit is small

9️⃣ QUIC in the Wild: Case Studies

Case 1: Meta (Facebook)

Meta deployed QUIC across their entire mobile app surface. Result:

  • P50 connection establishment: 30ms → 5ms (0-RTT resumption)
  • Video start time: Reduced by 15% on 3G networks
  • Rebuffer rate: Reduced by 20% on poor connections

Case 2: Google

Google was the first adopter. Their YouTube QUIC deployment showed:

  • Buffering time: 30% reduction in time spent rebuffering
  • Average video resolution: 9% higher on QUIC vs TCP
  • Connection migration: 100% transparent — users switching from Wi-Fi to cellular didn’t notice a hiccup

💡 Key Takeaways

  1. TCP’s in-order delivery guarantee is a liability for modern web — HTTP/2’s multiplexing is undermined by TCP-level HOL blocking
  2. QUIC eliminates HOL blocking at the transport layer — independent streams, independent loss recovery
  3. 0-RTT handshake is transformative for repeat visitors — literally zero round trips before data flows
  4. Connection migration is a killer feature for mobile — switch networks without dropping connections
  5. User-space transport is the future — QUIC can evolve at application pace, not kernel pace
  6. Adoption will grow as middleboxes catch up — the protocol is proven; deployment is a matter of infrastructure

QUIC and HTTP/3 aren’t just a new version of HTTP. They’re a fundamentally new transport layer for the internet, and the first major change to how data moves on the wire since TCP was designed in 1974.


📖 Series Navigation

 praneshnikhar.site / posts / http3-quic · Top 1:1