system-design · intermediate

Design a URL Shortener — Interview Walkthrough

Start here

A URL shortener turns a long link into a short one:

https://news.example.com/articles/2026/07/very-long-title...
https://sho.rt/aB3xY9

When users open the short link, the service redirects them to the original URL (usually HTTP 301/302).

This is a classic system design interview because it touches APIs, data modeling, hashing, caching, scale, and abuse—without requiring exotic domain knowledge.

What you will learn

  1. Clarify requirements like an interview.
  2. Estimate traffic with back-of-the-envelope math.
  3. Design write and read paths.
  4. Choose short-code generation strategies.
  5. Scale reads with cache and partitions.
  6. Cover analytics, expiry, and abuse at a practical level.

What you should know first

TopicWhy
System design foundationsStructured design approach
Answering frameworkInterview flow
Caching 101Hot redirect path
HTTP redirects301/302 behavior

Words you need before we begin

TermPlain English
Short codeThe aB3xY9 path segment.
RedirectResponse telling the browser to go to another URL.

| 301 vs 302 | Permanent vs temporary redirect (caching differs).

Base62Encoding using 0-9, A-Z, a-z (62 symbols).
CollisionTwo URLs mapped to the same short code.
Idempotent createCreating the same long URL twice can return the same code.
Hot keyExtremely popular short link receiving huge read QPS.

Simple story: coat check

You hand a long coat (long URL) and get a small ticket number (short code). Later you present the ticket and get the coat. The attendant’s binder is the database; a memo on the desk for today’s popular tickets is the cache.

Requirements (ask first)

Functional

Non-functional

Example scale (state assumptions)

High-level design

flowchart LR
  U[User] --> API[API / redirect service]
  API --> C[(Cache)]
  API --> DB[(Mapping DB)]
  API --> Gen[Code generator]

Step-by-step core design

Step 1 — API sketch

Step 2 — Code generation options

ApproachIdeaTrade-off
Hash + truncateHash long URL, encodeCollisions; same URL same code if careful
Counter + Base62Global/range counters encodedNeeds coordinated counter ranges
Random 64-bitRandom then insertCollision retry; simple

Interview-friendly: pre-allocated counter ranges per instance + Base62, or random with unique DB constraint.

Step 3 — Data model

Table links(code PK, long_url, created_at, owner_id, expires_at, click_count).

Unique on code. Optionally unique on hash of long URL for dedupe.

Step 4 — Redirect performance

Step 5 — Scale writes

Step 6 — Analytics

Do not do heavy analytics on the redirect path. Emit async click event to a queue/stream.

Step 7 — Abuse

Complete worked example: MVP → scale

Starting situation

Startup expects 1M links and 100 redirects/s peak next year.

Decisions

LayerMVPLater
DBSingle PostgresSharded by code
CacheRedisMulti-AZ Redis
Codes8-char Base62 random + unique7–8 chars with capacity planning
AnalyticsDaily batchStream + warehouse

Failure modes in discussion

How interviewers score you

Failure modes

ModeImpactMitigation
Hot short linkHot partition/CPUCache, CDN edge, replicate
Exhausted code spaceCreate failuresLonger codes; capacity math
Open redirect abuseReputation riskAllowlist schemes; scan
Sync analytics on pathLatency spikesAsync events
No uniqueness on codeWrong redirectsPrimary key + tests

Trade-offs

ChoiceBenefitCost
301 permanentFast client-side cacheHarder to change target
302 temporaryControlMore origin hits
Dedupe long URLsFewer rowsPrivacy/complexity
Custom aliasesProduct featureAbuse, uniqueness fights

Common misunderstandings

  1. “MD5 the URL and take six chars—done.” Collisions and predictability.
  2. “Put everything in one huge Redis forever.” Memory cost; still need durable store.
  3. “Global lock for counter.” Becomes a bottleneck—use ranges.
  4. “Redirect must update click count synchronously.” Prefer async.
  5. “Sharding is day one.” Start simpler; show evolution path.

Check your understanding

  1. What are the two primary APIs?
  2. Why is the system read-heavy?
  3. Name two code generation strategies.
  4. Why cache redirects?
  5. How should click analytics run?

Practice

  1. Compute how many 7-character Base62 codes exist roughly.
  2. Draw sequence for create and redirect with cache miss.
  3. Design rate limits for anonymous creates.
  4. Plan migration from one DB to sharded storage.
  5. Mock a 30-minute interview aloud with a timer.

Deeper production notes

Character set

Avoid ambiguous characters if humans type codes (0/O, 1/l). Product decision vs pure density.

GDPR and deletion

Deleting a mapping may be required; caches and CDN must honor invalidation. 301s cached by browsers are sticky—another reason some products prefer 302.

Multi-region

Redirects benefit from geo DNS + regional caches. Creates can be region-primary with async replication of mappings.

Additional teaching scenarios

Scenario A — peak load day

Traffic multiplies by ten. Re-read the failure modes and mark which appear first. Write the first mitigation for each.

Scenario B — mixed versions

Half the fleet runs the old build. Which assumptions break if protocols or schemas disagree? Prefer designs that tolerate one deploy window of mixed versions.

Scenario C — five-sentence teach-back

Explain the core idea without acronyms. If you cannot, revisit the simple story and worked example.

Scenario D — metrics and alerts

List three metrics and one alert threshold that name user impact or a resource that runs out.

Scenario E — non-goals

Write two problems this technique should **not** solve, to prevent cargo-cult adoption.

Scenario F — ownership

Name who owns dashboards, code changes, and pages. Blank ownership means the feature is not ready for broad enablement.

Revision summary

Glossary

TermDefinition
Short codeCompact identifier in the short URL path.
Base62Encoding alphabet of 62 alphanumeric chars.
RedirectHTTP response sending the client to another URL.

Abbreviations and terminology

What to learn next

  1. Answering framework
  2. Design a rate limiter
  3. Consistent hashing
  4. Database sharding

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

FAQ from first-time learners

Q: How long should codes be?
A: Long enough for capacity and unpredictability; interview with math, not a fixed magic number.

Q: SQL or NoSQL?
A: Both work; justify access patterns (lookup by code is key-value-like).

Q: Do I need Kafka?
A: Only if you justify analytics/stream needs—not as decoration.

Track: Distributed Systems

Previous: Rate Limiting Algorithms — Token Bucket, Windows, and Bursts

By Shubham Jain

All articles · Study paths

Shubham Jain · Learning Lab