Design a URL Shortener — Cheat Sheet
System Design Case Studies · 5 topics. Download the PDF or the Instagram carousel and share it.
Cheat Sheet · AiCanCode.org
Design a URL Shortener
System Design Case Studies5 topicsQuick revision reference
1
Requirements
A URL shortener converts long URLs into short codes (e.g. bit.ly/abc123) and redirects users transparently. Behind this simple facade lies a system that must generate unique short codes, store billions of mappings, and serve redirects with sub-20ms latency globally.
- ✓Given a long URL, generate a unique short URL (e.g. https://short.ly/abc123)
- ✓Redirect users from a short URL to the original long URL
- ✓Custom aliases — let users choose their own short code
- ✓Expiry — short URLs can be set to expire after a given time
- ✓Analytics — track click counts, referrer, and geography (stretch goal)
- ✓100M URLs created per day (≈ 1,160 writes/sec)
2
Scale Estimates
- ✓Writes: 100M / day ≈ 1,160 / sec
- ✓Reads (10:1): 1B / day ≈ 11,600 / sec
- ✓Storage per URL: ~500 bytes (URL + metadata)
- ✓Storage (5 years): 100M × 365 × 5 × 500B ≈ 91 TB
- ✓Cache target: 80% of reads served from Redis
3
Key Components
- ✓API Gateway / Load Balancer — Routes POST /shorten to the Write Service and GET /{code} to the Redirect Service. Handles TLS termination, rate limiting, and bot filtering.
- ✓Write Service — Generates a unique 7-character base62 code using a distributed counter. Writes the mapping to the primary database and optionally warms the cache.
- ✓Redirect Service — Receives a short code, checks Redis cache first (targeting 80% hit rate), falls back to the database on a miss. Returns HTTP 302 with the Location header set to the original URL.
- ✓Database (Wide-Column Store) — Stores { shortCode → { longUrl, userId, createdAt, expiresAt } }. A wide-column store like Cassandra or DynamoDB is ideal — the access pattern is almost exclusively single-key point lookups.
- ✓Cache (Redis) — Caches the hot 20% of URLs that account for 80% of traffic. TTL aligned with URL expiry. LRU eviction policy. Reduces database read load by ~80%.
- ✓Analytics Service (async) — Redirect Service publishes click events to Kafka. The Analytics Service consumes events asynchronously and writes aggregates to a separate store. Fully decoupled from the latency-critical redirect path.
4
Trade-offs
- ✓HTTP 301 vs 302 redirect → 302 Temporary: 301 is cached by browsers — analytics breaks and URLs cannot be updated or expired. 302 always hits our service.
- ✓Base62 counter vs MD5 hash for code generation → Base62 counter: Guaranteed uniqueness, predictable code length, no collision handling needed. MD5 truncation can collide and requires a retry loop.
- ✓SQL vs NoSQL for the mapping store → NoSQL (Cassandra / DynamoDB): Access pattern is pure key-value. NoSQL scales horizontally without sharding complexity. Only prefer SQL if analytics queries on the same data are a core requirement.
- ✓Sync vs async analytics → Async via Kafka: Click tracking must not add latency to the redirect. Decoupling via Kafka means analytics failures are invisible to the user.
5
Interview Tips
- ✓Start by clarifying scale. "100M URLs/day" vs "1,000 URLs/day" changes the architecture. Ask before drawing anything.
- ✓Know base62 vs MD5 and the collision trade-offs. Interviewers almost always probe code generation.
- ✓Mention 302 vs 301 proactively — it shows you think about product requirements (analytics), not just technical plumbing.
- ✓LRU cache eviction is the right choice here — explain why (recently accessed = likely accessed again).
- ✓If asked to scale writes, introduce a Snowflake-style ID generator rather than a single database auto-increment column.
- ✓Bring up the analytics decoupling via Kafka — it demonstrates you understand the critical path and know how to protect it.
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/system-design-cases