Design a URL Shortener
Beginner · 25 min read · High-Level Design, Case Studies: Core
Key generation, redirects at scale, caching and analytics.
A URL shortener (bit.ly, TinyURL) turns https://example.com/blog/2026/10/a-very-long-article-title?utm_source=newsletter into https://sho.rt/x7Kp2Qa, and redirects anyone who visits the short link.
1. Clarify the problem
Questions worth asking, and the answers we'll assume:
2. Requirements
Functional
3. Capacity estimation
So: writes are tiny. Reads are moderate but must be fast → cache aggressively. 3 TB of link data fits comfortably in a horizontally scalable KV store (or a sharded relational DB). Analytics is the largest data stream and should be decoupled from the redirect path.
4. API
Rate-limit POST /v1/links per API key and per IP — URL shorteners are prime spam/phishing tools.
5. Data model
The access pattern is a pure key lookup by code, with no joins on the hot path. Good choices: DynamoDB/Cassandra (partition key = code, scales horizontally, multi-region replication) or PostgreSQL/MySQL sharded by code (strong uniqueness, familiar).
6. High-level design
Create flow
7. Deep dives
Option A — hash the long URL (e.g., first 7 Base62 characters of SHA-256 or MD5).
8. Failure modes and scaling
9. Trade-offs summary
10. What interviewers look for
Interview questions
- Two users shorten the same long URL. Should they get the same code?
- A link goes viral and receives 500,000 requests per second. What breaks and how do you handle it?
- How do you prevent people from guessing other users' short links?
- Your key range allocator is a single database row. Isn't that a bottleneck?
Practice
Write your answer before opening the suggested one. Anything you mark "Partly" or "Missed it" comes back in your review deck.
Further reading
Key takeaways
- A URL shortener is read-heavy and latency-sensitive: cache in Redis and at the edge, keep analytics asynchronous.
- 7 Base62 characters give ~3.5 trillion codes — plenty for billions of links with a sparse, unguessable space.
- Generate codes with random + conditional insert, or range-allocated counters through a permutation; avoid enumerable sequences.
- Use 302 when analytics and deletion matter; 301 only to minimise load.
- Plan for viral links, expiry, abuse and multi-region reads.
Previous: Security Fundamentals · Next: Design a Distributed Rate Limiter