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 → urlin Redis with a long TTL. - Redirect type:
301caches in browsers (fewer hits);302lets 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.