Design a URL Shortener: System Design Interview Guide
701 words · Reviewed for accuracy

"Design a URL shortener" is the classic opening system design question for a reason: it's simple enough to finish in 45 minutes and rich enough to touch estimation, hashing, databases, caching, and scale. Here's the full walkthrough, in the order a strong candidate actually runs it.
The shape of the answer: requirements first, capacity second, API third, data model fourth, then the one genuinely interesting problem — turning a long URL into a short, unique, unguessable code — and finally scale. Don't skip to hashing in minute two.
Step 1 — Requirements (say them out loud)
Functional: given a long URL, return a short link; visiting the short link redirects to the original. Non-functional: redirects must be fast (it's a read path on every click), links shouldn't be enumerable (no trivially guessing other people's URLs), and the system is read-heavy. Clarify scope: custom aliases? Expiry? Analytics? Pick one extra, note the rest as future work — scope control is a senior signal.
Step 2 — Back-of-envelope capacity
Every number here is a labelled assumption for the sake of the exercise, and you should say exactly that: assume 100 million new short links created per month, and a 100:1 read-to-write ratio (people click far more than they create). That's roughly 40 writes and 4,000 reads per second — reads dominated by a hot few links. Storage: assume each record (code, long URL, metadata) is about 500 bytes, so 100 million records a month is ~50 GB monthly, ~600 GB a year before indexes. Fits on one database for a while; sharding is a growth conversation, not a day-one one.
Step 3 — API and data model
POST /api/shorten { "longUrl": "https://…" } → { "shortUrl": "https://sho.rt/x7kQ2p" }
GET /{code} → 301/302 redirect to the long URL
One table is genuinely enough to start: links(code PK, long_url, created_at, user_id). A key-value or document store works equally well — either is defensible if you justify it (see the SQL vs NoSQL decision). Choose 301 (permanent, browsers cache it — less load) versus 302 (temporary, every click hits you — enables analytics) and explain the trade-off; interviewers ask.
Step 4 — The interesting part: generating the code
Three mainstream approaches, and you should present them as a decision:
- Counter + base62. An ID generator hands out increasing integers; encode each in base62 (a–z, A–Z, 0–9). A 7-character base62 code covers about 3.5 trillion combinations — say that arithmetic out loud. Simple, collision-free, but sequential codes are guessable.
- Hash + truncate. MD5/SHA the long URL, take the first 7 characters. Unguessable, but truncation means collisions — so you check existence and append a salt or retry. Name the collision handling; that's the point of the question.
- Pre-generated keys (KGS). A service mints random codes offline into a "ready" table; the API just claims one. No runtime collision check, easy to scale horizontally.
Step 5 — Scale it
Now earn the "senior" checkbox. Reads: put a cache-aside tier in front — the hot links absorb most clicks, so most redirects never touch the database. Writes: 40/second is trivial; no heroics needed. Availability: app servers stateless behind a load balancer, database replicated. Growth path: when one database strains, shard by the code's hash — lookups by code stay single-shard. Close with monitoring and the abuse story (spam links, scanning), and you've covered the board.
Common mistakes
- Starting with hashing before requirements. The interviewer steers; let them.
- Truncating a hash without a collision strategy. That's the trap the question is built around.
- Forgetting the 301-vs-302 distinction — it's a free depth point.
- Designing for planetary scale when your own estimate says 40 writes/second. Match the machinery to the numbers you calculated.
FAQ
Which code-generation approach should I pick? Counter + base62 with an offset or shuffle if guessability matters; it keeps the design collision-free and easy to reason about. Mention KGS as the scale-out path.
SQL or NoSQL for the links table? Either. Justify with access patterns: "lookups are always by code, so a key-value store fits; I'd take SQL for the operational tooling." Justification beats brand choice.
Run this walkthrough under time pressure with Aissence mock interviews, and keep the system design spine beside you.