Back
LearnSystem Design PlaybookDesign a URL Shortener

Design a URL Shortener

1 min read

Design a URL Shortener (TinyURL / bit.ly)

1. Requirements

  • Functional: shorten a long URL; redirect a short URL; optional custom alias & expiry.
  • Non-functional: highly available, low-latency redirects. Read-heavy (~100:1 reads:writes).

2. Estimation

  • 100M new URLs/month → ~40 writes/sec.
  • Reads at 100:1 → ~4,000 redirects/sec.
  • Storage: 100M/mo × 5 yr × ~500 bytes ≈ 3 TB.

3. The core problem: generating short codes

Use a base62 alphabet [a-z A-Z 0-9]. With 7 chars: 62⁷ ≈ 3.5 trillion URLs.

Approach How Trade-off
Counter + base62 Encode an auto-increment ID Sequential, guessable
Hash Hash the URL, take 7 chars Collisions — check & retry

A robust pattern: a distributed ID generator hands each server a block of unique IDs, base62-encoded — no coordination on the hot path.

4. High-level design

Write:  Client ─▶ LB ─▶ App ─▶ ID gen ─▶ DB (id → longURL)
Read:   Client ─▶ LB ─▶ App ─▶ Cache ─▶ DB ─▶ 301 redirect

5. Deep dives

  • Caching: redirects are read-heavy & immutable — cache code → url in Redis with a long TTL.
  • Redirect type: 301 caches in browsers (fewer hits); 302 lets you count every click.
  • Analytics: fire a click event to a queue → process async so redirects stay fast.

Takeaway: the hard part isn't storage — it's generating unique codes at scale without coordination, and serving reads from cache.

Tip