Real-world Systems
12 min forge
URL Shortener Design
How to design a scalable URL shortening service like Bitly or TinyURL.
π URL Shortener: System Design
Designing a URL shortener is a classic system design interview question. It tests your ability to handle read-heavy traffic, generate unique IDs, and optimize for low latency.
1. Requirements
Functional
- Shortening: Given a long URL, return a much shorter, unique alias.
- Redirection: When a user hits the short URL, redirect them to the original long URL (HTTP 301/302).
- Custom Aliases: Users should be able to specify a custom short link (optional).
- Expiry: Links should have a default expiration time.
Non-Functional
- High Availability: Redirection must always work.
- Low Latency: Redirection should be near-instant.
- Uniqueness: No two long URLs should result in the same short URL (unless specified).
- Scalability: Handle millions of requests per day.
2. API Design
Shorten URL
POST /api/v1/shorten
- Request:
{ "longUrl": "https://example.com/very/long/path", "customAlias": "optional-nick" } - Response:
{ "shortUrl": "https://forge.ly/abc123" }
Redirect URL
GET /{shortCode}
- Response:
301 Redirectto the original long URL.
3. Storage Schema
We need a database to map shortCode to longUrl.
Database Choice: NoSQL (e.g., MongoDB/DynamoDB)
- Why? We don't need complex relations. A simple Key-Value store or Document store is faster and easier to scale.
- Schema:
shortCode(PK)longUrluserId(optional)createdAtexpiryDate
4. Short Code Generation Strategies
A. Hashing (MD5/SHA)
- Hash the long URL and take first 7 characters.
- Problem: Collisions. Two URLs might produce the same hash.
- Fix: Check DB for collisions, append a salt if it exists. (Expensive).
B. Base62 Encoding
- Convert a unique numeric ID (like
12345) to a string using characters[a-z, A-Z, 0-9]. - 7 characters in Base62 = $62^7 \approx 3.5$ trillion unique IDs.
- How to get a unique numeric ID? Use a Key Generation Service (KGS).
C. Key Generation Service (KGS)
- A dedicated service that pre-generates unique keys and stores them in a "Key Table".
- When a new URL needs shortening, just grab a key from the table.
- Scalability: Use two tables (Used vs. Unused) or keep keys in memory with persistent backup.
5. High-Level Architecture
mermaid Standardgraph TD User --> LB[Load Balancer] LB --> Web[Web Servers] Web --> Cache[Redis Cache] Cache --> DB[(NoSQL DB)] Web --> KGS[Key Generation Service] KGS --> KDB[(Key DB)]
6. Optimization: Caching & Redirection
Caching
- Redis should store the mapping of the most frequently accessed short URLs.
- Policy: LRU (Least Recently Used) is ideal.
301 vs 302 Redirect
- 301 (Permanent): Browser caches the redirection. Reduces load on our servers but makes analytics harder to track.
- 302 (Temporary): Browser asks our server every time. Better for tracking clicks/analytics, but higher server load.
7. Scalability & Maintenance
- Database Sharding: Shard based on the
shortCodehash. - Cleanup Service: A background worker that periodically deletes expired links.
- Analytics: Push click data to a Message Queue (Kafka) for processing without blocking the redirection flow.