Free full guide

URL Shortener

Design a scalable URL shortener for 100M daily active users.

00

Practice checkpoints

The interview rhythm stays compact, so the page can spend attention on the actual design decisions.

  1. 01
    Clarify scope
  2. 02
    Requirements + scale
  3. 03
    API + data model
  4. 04
    Draw architecture
  5. 05
    Deep dive
  6. 06
    Trade-off decision
01

Requirements that shape the design

Do not only state requirements. Ask for them. Each card pairs the design constraint with a clarification question you can say out loud before drawing the architecture.

Functional requirements

01Should users be able to pick a custom alias, or is a system-generated short code enough?

Users can submit a long URL and get back a unique short link — system-generated base62 code (letters + digits) by default, custom alias as an optional extra.

02Do links live forever, or do we need expiration and cleanup?

Users can set an optional expiration; an expired link stops redirecting and its code can be retired later.

03Is the redirect itself the core flow — does anything else have to happen on click?

Anyone who opens a short link is redirected to the original URL. This read path is the hot path the whole design serves; click events are emitted asynchronously, off the redirect.

04Do marketing campaigns need bulk creation - thousands of links in one call?

Support batch creation: a campaign mints thousands of links in one request - which stresses code allocation, never the redirect path.

05Can a link be retargeted to a new destination after creation?

Links are immutable by default; retargeting is an explicit optional feature, and using it must invalidate every cache layer holding the old destination.

06Who owns a link - can creators list and deactivate their own?

Links belong to their creator: list, deactivate, and retire - a deactivation propagates to caches within seconds, not at TTL expiry.

Out of scopeAnalytics dashboard — only async click-event emission stays in scope · User accounts, auth, and link-management UI · Spam and malicious-URL scanning

Non-functional requirements

01What read/write ratio should I assume — is this heavily read-skewed?

Read-heavy: at least 100:1 redirects to creates, and marketing-heavy deployments run closer to 1000:1 — ask which, then design the redirect path cache-first either way.

02How fast must a redirect feel to the user?

Redirect p95 under 100 ms — a cache hit answers in single-digit milliseconds, so the extra hop feels invisible.

03Must a brand-new link resolve instantly everywhere, or is a short delay fine?

Availability over consistency: 99.99% for redirects; a just-created link may take seconds to propagate to caches and replicas (eventual consistency accepted).

04How many total links should the code space and storage plan for?

Plan for ~1B links: 7-char base62 gives 62^7 ≈ 3.5 trillion codes of headroom; at ~1 KB per row total storage stays near 1 TB, shardable by short code.

05Can two links ever share a code — and can someone guess private codes?

Short codes must be globally unique — no collisions, ever. For private links, allocation must not be sequentially predictable: enumerable base62 codes leak private URLs, so randomize within allocated ranges.

Keep asking — the interview is a conversation

Real interviews probe far more than a tidy list. These are the scope questions that separate candidates who interrogate the problem from those who recite it.

  • Are custom aliases and expiration in scope, or system-generated permanent codes only?
  • What read/write ratio and DAU should I size for?
  • What p95 latency should a redirect hit?
  • Is eventual consistency acceptable for brand-new links?
  • Do we need click analytics now, or just leave the door open? The 301-vs-302 choice hangs on this.
02

Numbers that force architecture decisions

Treat every estimate as a pressure that justifies a component: cache, queue, partition, replica, worker pool, or fallback path.

01

Redirect read QPS

100M DAU × ~1 redirect each per day100,000,000 ÷ 86,400 s ≈ 1,160 QPS average · viral bursts ×5-10 ≈ 5-10K QPS peak

Cache + CDN must absorb the peak — the database never serves the redirect hot path.

02

Create write QPS

~1M new links per day1,000,000 ÷ 86,400 s ≈ 12 writes/s

Writes are trivial: no write scaling needed — the only write-side risk is code allocation contention, not row inserts.

03

Total storage

1B links × ~1 KB per row (code, long URL, owner, timestamps, TTL)10⁹ × 1 KB ≈ 1 TB

Fits a sharded store comfortably; the short_code index is the real working set.

04

Code space

7-character base62 codes (62 characters per position)62⁷ ≈ 3.5 × 10¹² codes vs 10⁹ links needed → ~3,500× headroom

Codes never run out — the real risk is predictability (enumerable codes), not exhaustion.

05

Cache size

Top ~20% of links serve ~80% of reads (Pareto)20% × 1 TB ≈ 200 GB

Feasible on a modest Redis cluster; the hottest viral links additionally sit on the CDN edge.

Decision example

The numbers

The numbers say one thing: reads outnumber writes about 100 to 1 and peak at 5-10K redirects per second, with under 100 ms to answer — so the redirect is the only path worth optimizing.

My choice

I would answer redirects from a cache first (Redis, plus CDN for the hottest links), so the database is never in the hot path. For creating links, a small key service hands each API server a batch of pre-made unique codes — creating a link never fights over a shared counter. Clicks get counted by dropping an event onto a stream; the redirect never waits for analytics.

Avoid

What I would NOT do: hash the long URL to make the code and retry whenever two URLs collide. Under load those retries pile up and creating a link becomes a lottery. Handing out pre-made unique codes makes collisions impossible instead of merely unlikely.

Change if

If accurate per-click analytics becomes a must-have, I would switch from 301 to 302 redirects: browsers stop caching the hop, every click reaches my servers and gets counted, and I accept the small extra latency.

03

Architecture path

Draw the write path and the read path as separate lanes — they carry different traffic and justify different components.

URL Shortener serviceClientWrite path — create a short linkAPI ServiceKey GenerationServiceDatabaseCache (pre-fill)Read path — redirect (the hot path)CDN / EdgeAPI ServiceCache301/302 RedirectAnalytics Streamasync click eventsservicestorequeue / logexternalasync

Start with the simple version: one picture, every component and relation. Dashed = asynchronous, off the hot path. A cache miss falls back to the database and refills the cache.

KGS hands out pre-generated unique code ranges, so creates never collide and never block on a shared counter.

Cache miss falls back to the database and refills the cache; click events go to the analytics stream off-path.

04

API and data model

Before optimizing, make the contract inspectable: endpoints, entities, ownership, retries, and state.

POST/urls

req{ long_url, custom_alias?, expires_at? }

res200 { short_url, expires_at } · 409 alias taken · 400 invalid URL

Idempotent per (owner, long_url): resubmits return the existing short_url instead of minting a new code.

GET/{short_code}

res301/302 + Location: long_url · 404 unknown code · 410 expired

301 lets browsers cache the redirect (fewer origin hits, loses click analytics); 302 sends every click through your servers (keeps analytics, adds a hop). The choice hangs on the analytics requirement — say it out loud.

Core entities

ShortLink

short_code (PK) · long_url · owner_id · created_at · expires_at · is_active

Shard by short_code so a redirect hits exactly one partition; an optional inverted index long_url → short_code enables create-time dedup.

User

user_id (PK) · email · created_at

05

Deep dive directions

Pick one lane for the final third of the interview. Each lane gives you the topic, the interviewer question it should answer, and the failure mode to avoid.

01

FocusHow short codes get made

AskHow do you guarantee two links never get the same code — counter + base62, or hashing? Why that one?

AvoidHashing the URL and hoping collisions are rare, without explaining the uniqueness guarantee.

02

FocusMaking the redirect fast

AskWalk one redirect end to end: where does the cache hit, what happens on a miss, and when does the database actually get touched?

AvoidReading the database on every redirect — the hot path must be cache-first.

03

Focus301 or 302

AskWhich redirect status do you return, and what does that choice do to browser caching and your click data?

AvoidPicking one arbitrarily — this choice IS the analytics decision.

04

FocusCounting clicks without slowing redirects

AskHow do you record clicks for 100M DAU without adding latency, and what happens if the analytics pipeline falls behind?

AvoidWriting analytics synchronously inside the redirect.

05

FocusOne link goes viral

AskA single link suddenly takes 10% of all traffic — what breaks first, and how do cache and CDN absorb it?

AvoidAssuming traffic is evenly spread — hot keys are the real load.

Ready to practice?

Talk through URL Shortener out loud and get AI scoring on the explanation.

Practice this with AI →