Mid-Level Classic Problems 8 min read

Design a URL Shortener (System Design Interview)

The Interview Question

Design a URL shortening service like bit.ly. It should generate short URLs, redirect users, and handle high traffic.

Expert Answer

Start by clarifying requirements: the system needs to take a long URL and return a short one, redirect short URLs to the original, handle analytics (click counts), and support high read throughput (reads far exceed writes). For the short code generation, you have two main approaches: hashing the URL with MD5/SHA256 and taking the first 6-7 characters (risk of collision), or using a counter-based approach with Base62 encoding (no collisions, predictable). A 7-character Base62 code gives you 62^7 = 3.5 trillion unique URLs. For storage, a relational database works fine — the data model is simple (short_code, original_url, created_at, click_count). Add an index on short_code for fast lookups. For scale, put a cache layer (Redis) in front of the database since the same popular URLs will be accessed repeatedly — this is a perfect caching use case with a high hit ratio. The redirect flow: user hits short URL → check Redis → if miss, check DB → return 301/302 redirect → increment click counter asynchronously.

Key Points to Hit in Your Answer

  • Clarify: read-heavy vs. write-heavy (URL shorteners are extremely read-heavy, ~100:1 ratio)
  • Base62 encoding with a counter avoids hash collisions entirely
  • 301 (permanent) vs 302 (temporary) redirect affects caching and analytics
  • Redis cache with LRU eviction handles the hot URL problem
  • Click analytics should be async (message queue) to not slow down redirects
  • At massive scale: consider consistent hashing for distributed cache, database sharding by short_code

Code Example

// Base62 encoding for short codes
const CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

function encode(num) {
  let result = '';
  while (num > 0) {
    result = CHARS[num % 62] + result;
    num = Math.floor(num / 62);
  }
  return result.padStart(7, '0');
}

// Redirect flow pseudocode
async function redirect(shortCode) {
  let url = await redis.get(shortCode);
  if (!url) {
    url = await db.query('SELECT original_url FROM urls WHERE short_code = ?', shortCode);
    await redis.set(shortCode, url, 'EX', 86400); // Cache 24h
  }
  analyticsQueue.push({ shortCode, timestamp: Date.now() }); // Async
  return redirect302(url);
}

What Interviewers Are Really Looking For

They want to see structured thinking: requirements → API design → data model → core algorithm → scale considerations. The 301 vs 302 tradeoff shows depth. Mentioning async analytics via a message queue shows you think about system coupling. At senior level, discuss database sharding strategy and cache invalidation.

Practice This Question with AI Grading

Reading about interview questions is a start — but practicing with real-time AI feedback is how you actually get better. Goliath Prep grades your answers instantly and tells you exactly what you're missing.

Start Practicing Free →