Lesson 61 — System Design V: URL shortener

~20 minutes · Day 79 · system design

Tonight's interview design is a URL shortener: turn a long URL into something like /aB7x9Q, then redirect anyone who visits that code. It looks tiny, which is why interviewers like it. The product is simple enough to draw, but it exposes the real system-design habit: find the path that gets the most traffic, then protect it.

The invariant

A tiny write path (issue an ID, base62-encode it) feeding an enormous read path — design for the reads: one lookup per redirect, cache the hot links.

The script

The system-design script is always: requirements → estimate scale → API → data model → high-level boxes → deep-dive the bottleneck → failure modes. Apply it in that order; do not jump straight to boxes.

  1. Requirements. Create a short code for a long URL. Redirect fast. Support expiry. Basic analytics can lag behind the user-facing redirect.
  2. Estimate scale. Assume reads dominate writes. The System Design Primer example uses 10 million writes/month and 100 million reads/month, a 10:1 read-heavy system.
  3. API. POST /links creates a code. GET /{code} returns an HTTP 302 redirect with the target in the Location header.
  4. Data model. Store code, long_url, created_at, expires_at, and optional owner_id. Make code unique.
  5. High-level boxes. Separate create traffic from redirect traffic. The redirect service checks cache first, database second.
  6. Deep-dive the bottleneck. The hot path is GET /{code}: one lookup, then redirect. Analytics, abuse checks, and counters must not sit in front of the redirect.
  7. Failure modes. If the cache is down, fall back to the database. If the database misses, return 404 or 410. If ID generation fails, stop writes rather than reusing codes.
POST /links
{ "long_url": "https://example.com/really/long/path" }

201 Created
{ "short_url": "https://sho.rt/aB7x9Q" }

GET /aB7x9Q
302 Found
Location: https://example.com/really/long/path

The write path can be boring: ask an ID generator for the next number, Base62-encode it, save the mapping, return the code. Boring is good. The read path is where the system earns its design.

The architecture diagram

URL shortener architecture Create requests issue IDs and write mappings. Redirect requests check cache first, then database on miss, while analytics are handled asynchronously. Browser GET /aB7x9Q Edge / LB route reads Redirect API lookup code return 302 Hot-link cache code → long_url Links database source of truth Write API POST /links ID service 1, 2, 3... Analytics queue Key insight: cache hit means the database never sees that redirect request.

The bottleneck deep-dive

The bottleneck is not making the short code. It is serving the same popular code again and again without melting the database. Three cache choices are worth saying out loud:

For a first interview pass, choose cache-aside with bounded LRU, then mention that a production system may upgrade the admission policy if traffic is extremely skewed.

Numbers that matter

FigureWhy it mattersSource
62^7 ≈ 3.5 trillion codesSeven Base62 characters leave a very large code space.Base62 alphabet
1 request/sec ≈ 2.5 million/monthFast mental conversion for back-of-the-envelope sizing.System Design Primer
10:1 reads to writesGood starter assumption for URL-shortener traffic.System Design Primer
Cache examples exceed 100k ops/secIn-memory cache absorbs hot redirects before the database.Redis benchmarks
302 + Location headerThe redirect response only needs the target URL.MDN HTTP 302

Practice — answer before you scroll past

1. Redirects are far more common than creates. What should you optimize first?

2. Which redirect-path design keeps the user-facing request shortest?

3. A celebrity shares one short link; millions click it. Which cache policy is the clean default?

4. Why use an ID generator before Base62?

Your move (tonight)

Redraw the architecture diagram from memory on paper. Then explain the design out loud in 5 minutes as if an interviewer is listening: requirements, scale, API, data model, boxes, bottleneck, failures. No LeetCode tonight.

For the encode step in your Notion tracker, write the invariant in your own words. The sentence should mention both sides: tiny write path, enormous read path.

One primary source

Read System Design Primer — Design Pastebin.com (or Bit.ly) after your redraw, as the “compare” step. Focus on where it adds cache, replicas, and scaling only after the basic design is clear.


Stuck or curious? Ask your teacher (the agent) — that's what it's for.