System Design Visualized
System design interview · Easy · about 35 minutes

Design a URL shortener

Design a URL shortening service like TinyURL: turn a long URL into a short alias, and redirect anyone who visits the alias to the original URL.

hashingIDscaching
Practise it in the interview simulatorDraw your design on a canvas, stress test it with real traffic, and get a scored report. Or watch this answer build itself, step by step.

1. Clarify the requirements

Before drawing anything, ask questions. These are the answers an interviewer would typically give:

How many URLs?
100 million new short URLs per day.
How short?
As short as possible; characters 0-9, a-z, A-Z.
How long are URLs kept?
10 years.
Read/write ratio?
10 redirects for every new URL.
Can URLs be deleted or edited?
No, for simplicity.
Analytics?
Click analytics would be nice, so think about the redirect status code.

2. Estimate the scale

Assumptions: 100M new URLs per day, 10:1 read/write, kept for 10 years, ~100 bytes per record.

  • Write QPS: about 1160 writes/s100M ÷ 86,400 ≈ 1,160/s.
  • Redirect QPS: about 12K reads/s10 × 1,160 = 11,600/s.
  • Records in 10 years: about 365B records100M × 365 × 10 = 365 billion.
  • Storage for 10 years: about 36.5 TB365B × 100 bytes = 36.5 TB.

3. The high-level design

UsersLoad balancerURL serviceURL storeDynamoDB / CassandraRedirect cacheRedisID generatorMetrics & alerts
The reference design. Dashed arrows are asynchronous.
  1. Users reach a stateless URL serviceA load balancer spreads requests over stateless servers. Shortening and redirecting are both simple lookups, so the service scales by adding servers.
  2. Store short → long mappingsBillions of tiny records read by key: a key-value store sharded by short code, with three replicas, fits perfectly.
  3. Cache the hot linksRedirects outnumber new links 10 to 1, and a few links get most clicks. An in-memory cache answers them without touching the database.
  4. Unique IDs without collisionsA Snowflake-style ID generator hands out unique, time-ordered IDs; base62-encoding one gives the short code, so there's no hash collision to check.
  5. Watch it in productionMetrics and alerts close the loop: redirect p99, cache hit ratio and 4xx/5xx rates.

4. The components and what each one does

Load balancer Load balancer
Spreads requests over the stateless servers behind it, health-checks them and routes around a dead one. Rate limits abusive clients.
URL service App servers
Stateless. Shorten: new unique ID → base62 (7 characters, 62⁷ ≈ 3.5 trillion codes). Redirect: look up the long URL and answer 301 (cached by browsers) or 302 (every click counted). Rate limits link creation.
URL store NoSQL / KV store · DynamoDB / Cassandra
short code → long URL. Key-value, sharded by short code, 3 replicas with failover.
Redirect cache Cache · Redis
short code → long URL, LRU eviction. Hot links are served from memory.
ID generator Service
Snowflake-style unique IDs (timestamp + machine + sequence): no collisions, no coordination between servers.
Metrics & alerts Metrics & alerts
Dashboards and alerts on p99 latency, error rate, queue depth and cache hit ratio, so a bottleneck shows up before it becomes an outage.

5. Deep dive: generating short codes

How do you generate unique short codes? Compare hashing + collision checks with base62 encoding of a unique ID. How long must the code be?

  • 62⁷ ≈ 3.5 trillion, enough for 365 billion URLs: 7 characters.
  • Hash (CRC32/MD5) and take 7 chars → collisions → check DB (Bloom filter helps).
  • Or: get a unique ID (Snowflake) and base62-encode it: no collisions, but codes are guessable.

6. What interviewers listen for

  • Shorten and redirect APIsPOST /api/v1/data/shorten {longUrl} and GET /api/v1/{shortUrl}.
  • 301 vs 302 redirect choice301 is cached by browsers (less load, no analytics); 302 hits you every time (analytics).
  • Code length from the numbers (7 base62 chars)62⁷ ≈ 3.5 × 10¹² > 365 × 10⁹.
  • A code generation strategyExplain exactly how a long URL becomes a short, unique code.
  • Collisions handled (or avoided with unique IDs)Hashing collides; either check (Bloom filter) and retry, or use a unique ID generator.
  • Database replication and failoverA single database is a single point of failure. Replicas give redundancy and read capacity; failover promotes a replica when the primary dies.
  • Partition (shard) data as it growsOne machine eventually can't hold the data or the write load. Say how you'd split it and by which key.

7. Follow-up questions

  1. Security notices people can enumerate everyone's links by incrementing the code. Is that a problem in your design, and how would you fix it?
    • Sequential IDs are guessable (base62 of a counter)
    • Add randomness: random/hashed codes, or shuffle/encrypt IDs
  2. A short link is posted during the Super Bowl and gets 1M redirects a minute. What happens?
    • Served from cache (or CDN/edge)
    • 301 can offload repeated browser visits
    • Rate limiting protects the service
  3. Marketing wants click counts per link per day. What do you change?
    • Use 302 so every click reaches you
    • Log clicks asynchronously (queue/stream) and aggregate

The design in a nutshell

  • LB → stateless web servers. Shorten: get a unique ID (Snowflake), base62-encode it (7 chars), store (id, shortURL, longURL) in a sharded KV/DB; return 7-char code.
  • Redirect: look up cache → DB on miss → 301 (or 302 for analytics).
  • Cache hot mappings; rate-limit shortening; replicate the store; Bloom filter if using hashing.

Related lessons: How long should the short code be? · Approach 1: Hash + collision resolution · Approach 2: Base-62 conversion ✅

Now design it yourself

Reading an answer isn't the same as giving one. Draw URL shortener on the canvas, defend your numbers, survive a 10× traffic spike, and see exactly what an interviewer would flag.

Open the interview simulator