Design a URL Shortener: System Design Interview Guide
Last updated August 29, 2026

Short answer: A URL shortener design is solved in a fixed order: requirements, capacity estimates, API, data model, then the interesting part, how to generate short codes, and finally scaling. Say your assumptions aloud, estimate reads versus writes, and explain how you avoid code collisions and serve redirects quickly.
"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.
Put this into practice
Continue with the Aissence workflow this guide supports.