100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

How to Design a URL Shortener?

Learn how to design a URL shortener system: base62 encoding, caching, database schema, and redirect trade-offs explained for interviews.

mediumQ15 of 224 in System Design Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

A URL shortener maps a long URL to a short unique code by generating a base62 identifier (via a counter, hash, or random string), storing the mapping in a key-value store, and using a fast redirect service that reads the code and issues an HTTP 301/302 to the original URL.

The write path takes a long URL, generates a short code (a monotonically increasing counter encoded in base62, or a hash of the URL truncated to 6-8 characters with collision retry), and stores {code -> longUrl} in a database such as DynamoDB or a sharded relational store, keyed for O(1) lookup. The read path is far more frequent than the write path, so it sits behind a cache like Redis to absorb hot-key traffic and reduce database load, and a CDN or edge layer can cache redirects for popular links. Key design choices include the encoding scheme (counter-based avoids collisions but needs coordination across servers via ranges; hash-based is stateless but needs collision handling), a 301 (permanent, cacheable) versus 302 (temporary, trackable) redirect trade-off, and analytics capture (click counts) done asynchronously so it never blocks the redirect. At scale, the system also needs custom alias support, expiration/TTL, and rate limiting to prevent abuse.

  • Compact links that are easy to share and fit character limits
  • Fast O(1) redirect lookups via key-value storage and caching
  • Enables click analytics without slowing down the redirect path
  • Custom aliases and expiry give product flexibility

AI Mentor Explanation

A URL shortener is like assigning each fielding position a short code, such as slip or gully, instead of shouting the full description every time. The captain looks up the short code in a card that maps it to the full role โ€” that card is the database. Popular calls like fine leg get remembered instantly by everyone on the field, the way a cache keeps hot redirects fast. The short code always resolves back to exactly one long, well-defined position.

Step-by-Step Explanation

  1. Step 1

    Generate a short code

    Use a base62-encoded counter or a truncated hash of the long URL, with collision retry for hash-based schemes.

  2. Step 2

    Persist the mapping

    Store {shortCode -> longUrl} in a key-value store or sharded database keyed by shortCode for O(1) reads.

  3. Step 3

    Serve redirects through a cache

    Put a Redis or CDN cache in front of the database since reads vastly outnumber writes.

  4. Step 4

    Track clicks asynchronously

    Log analytics events to a queue so redirect latency is never blocked by write-heavy tracking.

What Interviewer Expects

  • A clear encoding strategy (counter vs hash) with collision handling
  • Read-heavy traffic pattern recognized and addressed with caching
  • Database schema choice justified for O(1) lookups at scale
  • Awareness of 301 vs 302 redirect trade-offs and analytics decoupling

Common Mistakes

  • Using an auto-increment ID without base62 encoding, producing long codes
  • Ignoring hash collisions when generating codes from URL hashes
  • Not accounting for the read-heavy skew and omitting a cache layer
  • Blocking the redirect response on synchronous analytics writes

Best Answer (HR Friendly)

โ€œA URL shortener takes a long link and generates a short unique code for it, then stores that mapping so future visits to the short link can be quickly redirected to the original. Because far more people click links than create them, I would focus on making reads fast with caching and keep the code-generation and storage simple and collision-free.โ€

Code Example

Base62 short-code generation and redirect lookup
const ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

function encodeBase62(num) {
  if (num === 0) return ALPHABET[0];
  let code = "";
  while (num > 0) {
    code = ALPHABET[num % 62] + code;
    num = Math.floor(num / 62);
  }
  return code;
}

async function createShortUrl(longUrl, db, counter) {
  const id = await counter.next(); // globally unique, monotonically increasing
  const shortCode = encodeBase62(id);
  await db.put({ shortCode, longUrl, createdAt: Date.now() });
  return `https://sv.link/${shortCode}`;
}

async function resolveShortUrl(shortCode, cache, db) {
  const cached = await cache.get(shortCode);
  if (cached) return cached;
  const record = await db.get(shortCode);
  if (!record) throw new Error("Not found");
  await cache.set(shortCode, record.longUrl, { ttlSeconds: 3600 });
  return record.longUrl;
}

Follow-up Questions

  • How would you handle collisions in a hash-based short-code scheme?
  • How do you scale short-code generation across multiple servers without collisions?
  • Would you use a 301 or 302 redirect, and why does it matter?
  • How would you design custom aliases and link expiration?

MCQ Practice

1. Why is a cache placed in front of the database in a URL shortener design?

URL shorteners are extremely read-heavy since each link is clicked far more often than it is created, so caching hot redirects reduces database load and latency.

2. What is a key advantage of counter-based short-code generation over hashing?

A monotonically increasing counter encoded in base62 never repeats, so it avoids the collision handling that hash-based schemes require.

3. Why should click analytics be logged asynchronously rather than synchronously?

Decoupling analytics via a queue keeps the critical redirect path fast, since users should not wait on tracking writes to be redirected.

Flash Cards

Why base62 encoding for short codes? โ€” It packs more values into fewer characters using digits and both letter cases, producing compact URLs.

Why cache redirects? โ€” Because reads (clicks) vastly outnumber writes (link creation), so caching hot codes cuts database load.

301 vs 302 redirect? โ€” 301 is permanent and cacheable by browsers; 302 is temporary and lets the server track every click.

How to avoid short-code collisions across servers? โ€” Use a coordinated counter (e.g., allocated ID ranges) or a hash with a collision-retry loop.

1 / 4

Continue Learning