URL Shortener System Design Interview: Read, Write, Redirect
Design a URL shortener out loud in the right order: requirements, rounded estimates, the short-code decision, the redirect read path, and the trade-offs you defend.
In a url shortener system design interview, the interviewer wants to hear you scope the problem, round the numbers, commit to one way of generating the short code, and then defend that choice when pushed. The design itself is small. The judgment is the point. Most candidates lose marks not by choosing the wrong option but by listing components and never saying why. This walkthrough gives you an order to speak in, the sentences to say, and the trade-offs to name before you are asked.
What the url shortener system design interview is really testing
It is a small system with one hard part: the short code. Say that out loud early, because it tells the interviewer you can tell the crux from the scaffolding.
Four things are usually being judged: how you scope, how you generate codes on the write path, how fast you can make the redirect on the read path, and whether you can defend a trade-off without wobbling. The design is a vehicle for those four.
Open with a 30-second script so the rest of the conversation has a shape:
"A URL shortener takes a long URL and returns a short code that redirects to it. I'll clarify requirements, size it roughly, design the write and read paths, then cover storage, trade-offs and failure modes. The interesting decision is how we generate the short code, so I'll spend time there."
That last sentence does real work. It signals where the depth will be, so the interviewer knows you are not stalling when you slow down.
Requirements first: what to ask before you draw anything
Ask a short, targeted set of questions, then write the answers in a requirements box on the board and read it back. That box becomes your checklist for the rest of the interview.
Functional questions worth asking:
- Do users need custom aliases, or only generated codes?
- Do links expire, and who sets the expiry?
- Do we track clicks, and how fresh does that data need to be?
- Can a user edit or delete a link?
- One short link per long URL, or many?
Non-functional questions:
- Is the workload read-heavy or write-heavy? Redirects usually far outnumber creations.
- What redirect latency is acceptable?
- How long must links live?
- Do we need abuse and spam handling, such as blocking known malicious destinations?
State the assumptions you will proceed on, even if the interviewer shrugs. "I'll assume reads dominate, links are permanent by default, click counts can be eventually consistent, and custom aliases are a stretch goal." Then move on. For a deeper treatment of this step, see Capacity Estimation System Design Interview: Round Numbers.
Round the numbers before you choose a design
Round aggressively and say your assumptions out loud. The interviewer is checking that you can estimate, not that you know real traffic. Here is a fully worked example you can adapt; every figure is an assumption, not a measurement.
- Writes: assume a few million new links a day.
- Reads: assume redirects outnumber creations by a wide margin, so reads per second are far higher than writes per second. Divide the daily read count by the seconds in a day and round.
- Code space: 7 characters from a 62-character alphabet (a–z, A–Z, 0–9) gives 62^7, which is a little over 3.5 trillion combinations. That is far more than the links we will ever store, which is why collisions are rare but not impossible.
- Storage: assume about 500 bytes per record (code, URL, owner, timestamps). Multiply by your daily write count to get new records per day, then by 365 for a year. The record is small; the index on the short code is what grows with read traffic.
The read:write ratio is the number that shapes everything. A high ratio tells you to cache the redirect path and keep the write path simple. If the interviewer says the ratio is closer to 1:1, your caching argument weakens and you should say so.
The core decision: how do you generate the short code?
Put three options side by side and compare them on collisions, coordination and guessability. This is the section where the interviewer learns the most about you.
| Strategy | Collisions | Coordination | Guessable |
|---|---|---|---|
| Counter plus base62 | None, if the counter is unique | Needs one authoritative counter or a partitioned range | Yes, sequential codes are predictable |
| Hash of the long URL | Possible; needs detection and a retry or salt | None beyond the hash | No, but the same URL always maps to the same code |
| Random code plus uniqueness check | Possible; needs a lookup before write | Read-then-write, or an insert that fails on duplicate | No |
A spoken recommendation with a reason and a reversal clause sounds like this:
"I'd use a counter with base62 encoding because it gives unique codes with no collision handling and the shortest possible codes. What would change my mind is guessability: if links must not be enumerable, for example for private documents, I'd switch to random codes and pay for the uniqueness check."
That "what would change my mind" clause is the sentence interviewers listen for. It shows the choice is a judgment, not a memorised answer. The same habit is worth building across domains; Distributed Systems Interview Questions: Name the Trade-Off covers the pattern.
The write path: from long URL to stored record
Walk the request in order, and keep it short.
- Validate the URL: scheme, length, and a basic abuse check.
- Check for an existing mapping if the requirements asked for dedupe; otherwise skip this.
- Generate the code using the strategy you chose.
- Write the record mapping code to long URL, plus owner and creation time.
- Return the short link.
If you chose a counter, say where it lives. A single counter service is a bottleneck and a single point of failure, so a common answer is to hand each application server a block of numbers in advance. If the counter is unavailable, servers can keep serving from their current block, which buys time.
Mention idempotency: if the client retries the same create request, a dedupe check on the long URL plus owner returns the existing code instead of a second one. That one sentence answers a follow-up before it is asked.
The read path: making the redirect fast
The redirect is the part users feel, so design it for the cache.
- Receive the code.
- Look up the long URL, checking the cache first.
- Return a redirect response to the client.
- Record the click asynchronously.
Explain why this path is cache-friendly: codes are immutable once created, so a cached mapping never goes stale unless a link is deleted. The cache key is the short code. A cache miss costs one database lookup, which is why the cache hit rate matters more than the database choice.
Keep click analytics off the critical path. Push the click event to a queue and let a separate worker write it. Analytics can lag by seconds without anyone noticing; a redirect cannot.
Storage and scale: what changes as links and traffic grow
The access pattern is a single key-value lookup by short code, so a simple key-value store or a table with a primary key on the short code fits. The index is the whole design; the value is tiny.
Shard by short code, not by user. Sharding by code spreads reads evenly because codes are effectively random with respect to traffic. Sharding by user concentrates a heavy user's links on one shard and makes hot links worse.
For expiry, store an expiry timestamp and let a background job delete in batches by expiry index, rather than scanning the whole store. Say that out loud; it shows you thought about cleanup without being asked.
Trade-offs to say out loud, and the follow-ups to expect
Name these before the interviewer does, and say the cost in one sentence each:
- Sequential vs random codes: "Sequential codes are shorter and collision-free, but anyone can walk the range, so I'd only use them where links are public."
- Cache vs database read: "The cache makes the redirect fast; the price is a short stale window when a link is deleted."
- Synchronous vs asynchronous analytics: "I'd write clicks asynchronously because a few seconds of lag on a count is invisible, while a slow redirect is not."
- Dedupe vs simplicity: "One code per URL saves storage, but it adds a lookup to every write, so I'd only do it if the requirements ask."
Three likely follow-ups, with a one-line answer each:
- Custom aliases: reserve them in the same namespace, check uniqueness on write, and reject reserved words.
- Hot links: a viral link is a cache hit, so it is cheap; protect the cache with a short TTL and a request cap per code.
- Abuse: check destinations against a blocklist on write, and rate-limit creation per account.
The three mistakes that cost the most marks
Most weak walkthroughs share the same three faults. Here is each one with a fix.
Jumping to components. Candidates draw a load balancer and a database before stating a requirement. The fix is a sentence: "Before I draw, let me confirm the read:write ratio, because it decides whether I cache."
Skipping estimates. Without numbers, every design choice is an opinion. Round to one significant figure and move on.
Never stating a trade-off. This is the most common and the most fixable. A weak phrasing is "I'd use a counter because it's simpler." A stronger phrasing is:
"I'd use a counter because it removes collision handling entirely, which keeps the write path short. The cost is that codes are guessable, so if privacy matters I'd accept the extra lookup and use random codes."
The difference is not the choice. It is that the second version names the cost and the condition that would flip it.
How to practise this walkthrough before the interview
Rehearse in one 25-minute block, four parts:
- 5 minutes: requirements and rounded estimates, out loud.
- 10 minutes: the design, spoken in the order above.
- 5 minutes: trade-offs and the three follow-ups.
- 5 minutes: self-review.
Record yourself and check three things: did you state a requirement before drawing, did you give at least one number, and did you say "what would change my mind" at least once? If any answer is no, redo that part only.
Practise the code-generation decision three different ways until it sounds like reasoning rather than recitation. The goal is not a perfect script; it is a habit of naming the cost. If you want help making talking points sound like your own words, see Sound Natural With Talking Points Interview Guide.
Before you walk in
The url shortener system design interview rewards order and honesty more than cleverness. Scope it, round it, commit to one code-generation strategy, and say what would change your mind. Your next step: set a timer for 25 minutes and record one full run, then listen back only for the three mistakes above.
Frequently asked questions
Should I use base62 or base64 for the short code, and does it matter?
Base62 is the safer default because its alphabet is URL-safe and avoids the + and / characters that base64 can produce, plus padding. The size difference is small; the real decision is whether codes are sequential or random. Pick one, state why, and move on rather than spending minutes on alphabet choice.
How do I handle custom aliases without breaking the code generator?
Put custom aliases in the same namespace as generated codes and check uniqueness on write, treating a clash as a validation error shown to the user. Reserve a block of words you never generate, such as admin or api, so a user cannot claim a path the service needs. Generated codes then skip anything already taken.
What if the interviewer asks me to add click analytics mid-interview?
Accept it and keep the redirect fast. Emit a click event to a queue from the redirect handler, then let a separate consumer aggregate counts by code and time bucket. Say that counts will lag by seconds and that this is acceptable; if the interviewer wants real-time counts, name the extra cost rather than pretending it is free.
How deep should I go on the database choice for such a small record?
One sentence is usually enough: the access pattern is a single lookup by short code, so a key-value store or a table keyed on the short code fits, and the index matters more than the engine. Spend your remaining time on code generation and the read path, where the real trade-offs live.
Is it okay to assume a single counter service, or will that be marked down?
Start with one counter if you like, but say the fix in the same breath: "Each server takes a block of numbers, so a counter outage only stops new blocks, not serving." If the interviewer pushes on failover, describe a standby counter that takes over with a gap in the sequence, and note that gaps are harmless because codes only need to be unique, not contiguous.