sydepsystem design atlas

Designing a URL shortener: the system design interview classic

January 21, 2025 · sydep team · 2 min read

The URL shortener is a system design interview staple for a reason: it's small enough to fully design in 45 minutes, but it touches ID generation, caching, storage trade-offs, and read/write scaling — a good proxy for how you reason about systems in general.

The core requirements

  • Given a long URL, generate a short, unique key and store the mapping.
  • Given a short key, redirect to the original URL with low latency.
  • Reads vastly outnumber writes — short links get clicked far more often than they're created.

ID generation is the first real decision

Three common approaches, each with different trade-offs:

  • Random string + collision check — simple, but requires a uniqueness check (and retry) on every write.
  • Base62-encoded auto-increment counter — guarantees uniqueness for free, but a single global counter can become a write bottleneck at scale, and reveals roughly how many links exist.
  • Pre-generated key ranges handed out to write nodes — the practical middle ground: a coordination service hands each writer a range of keys to consume, avoiding both the collision-retry problem and the single-counter bottleneck.

Why reads dominate the design

Because redirects vastly outnumber creations, the redirect path is where almost all of the engineering effort goes: an in-memory or CDN-edge cache in front of the primary key-value lookup, with the database as the fallback path for cache misses. Whether you reach for Redis, a CDN's edge KV store, or an in-process LRU cache depends on your latency budget and read volume — but the shape of the solution (cache-in-front-of-store) is the same at any scale.

Explore the full component layout — including where the cache sits relative to the redirect service and the ID generator — in the URL shortener reference.

What interviewers are actually probing for

Not whether you memorized "use Base62." They want to see you:

  1. Separate the write path (create short link) from the read path (redirect) explicitly, since they have very different traffic profiles.
  2. Reason about uniqueness without a naive "check and retry forever" loop.
  3. Identify caching as the lever that makes the redirect path fast, and know roughly where in the stack to put it.
  4. Talk about analytics (click counts, referrers) as an async, non-blocking side effect of the redirect — never on the critical path.

Once you've got the shape down on paper, it's worth dragging the actual components into a canvas and seeing how they connect — open this system in the app to explore it interactively.