Lesson 6 of 15
31. Design a URL Shortener

31.5 What does the whole system look like?

3 min read+10 XP

Step 4: High-level design (10 minutes)

Start simple, then add only what the numbers asked for.

the final high-level design: redirects are served from Redis, writes go through ID blocks, clicks are counted asynchronously.

Figure: the final design. Notice the redirect (green) path never touches the ticket server or the analytics pipeline.

Redirect, step by step:

  1. The user opens sho.rt/aB3x9Qz. The load balancer sends it to any app server (all stateless, Chapter 7).
  2. The app server checks Redis for aB3x9Qz. On a hit, done.
  3. On a miss, it reads a read replica of the database, puts the answer in Redis with a TTL, and continues (cache-aside, Chapter 12).
  4. It replies 302 with the long URL, and drops a click event on a queue without waiting.

Create, step by step:

  1. POST /api/links reaches any app server.
  2. The server takes the next ID from its own block of IDs (leased from the ticket server, 31.6), turns it into a 7-character code, and inserts the row into the primary database.
  3. It returns the short URL.

Interviewer pushback:

  • "Walk me through what happens if Redis is down." → Every redirect becomes a miss and goes to the replicas. They must be sized to survive that for a while, with timeouts on the Redis call so a dead cache doesn't make every request hang (Chapter 29).
  • "Why read replicas?" → Misses and the occasional cache restart shouldn't load the primary, which handles all creates. Replicas also give us a failover target if the primary dies (Chapter 14).

Memory code: "Draw it simple, walk it through." Then add only what the numbers asked for: a cache for reads, replicas for safety, a queue for counting.


The interviewer usually picks one or two. A strong candidate offers: "The two interesting parts are generating unique codes and keeping redirects fast. Which would you like?"