Cheat SheetsSystem Design Case StudiesDesign a URL Shortener

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