1. Requirements
Functional Requirements
- Generate short URL for a given long URL
- Redirect short URL → original URL
- Optional:
- Custom aliases
- Expiration time
- Analytics (click count)
Non-Functional Requirements
- Latency: < 50ms redirect
- Throughput: High read-heavy system (~100:1 read/write)
- Scalability: Billions of URLs
- Availability: Very high (redirect must not fail)
- Consistency: Eventual consistency acceptable for analytics
2. Estimations
Traffic
- Writes: ~10K/sec
- Reads (redirects): ~1M/sec
Storage
Assume:
- 100B URLs over time
- Each record ~200 bytes
👉 Total ≈ 20 TB → requires distributed storage
Read/Write Pattern
- Highly read-heavy
- Requires aggressive caching
3. API Design
3.1 Create Short URL
POST /shorten
Request:
{
"long_url": "https://example.com/abc",
"custom_alias": "optional",
"expiry": "optional"
}
Response:
{
"short_url": "https://sho.rt/xyz123"
}
3.2 Redirect
GET /{short_code}
Response:
- HTTP 302 → redirect to long URL
3.3 Analytics (Optional)
GET /analytics/{short_code}
4. Data Storage & Design
4.1 Database (Primary Store)
Use:
- Distributed KV store (e.g. Amazon DynamoDB / Cassandra)
Schema:
short_code (PK)
long_url
created_at
expiry
user_id
4.2 Cache (Critical)
Use:
- Redis
Key:
short_code → long_url
5. High-Level Architecture (HLD)
System divided into:
5.1 Data Plane (Redirect Flow)
- Client hits short URL
- Request goes to CDN
- CDN checks cache:
- If hit → redirect
- If miss → go to backend
- Backend:
- Check Redis cache
- If miss → fetch from DB
- Return 302 redirect
5.2 Control Plane (Short URL Creation)
- Client sends long URL
- Service generates short code
- Store mapping in DB
- Cache in Redis
6. Detailed Breakdown
6.1 Short Code Generation
Option 1: Hashing (Not ideal)
- Collisions possible ❌
Option 2: Counter + Base62 (Preferred)
ID → Base62 encoding → short_code
Example:
123456 → "abcD"
👉 Benefits:
- Unique
- Compact
- Predictable length
6.2 Read Optimization (Critical)
- CDN caching (edge)
- Redis caching (hot data)
👉 Most requests never hit DB
6.3 Write Path
- Generate ID
- Encode → short code
- Store in DB
- Populate cache
6.4 Scaling Strategy
Stateless App Servers
- No local state
- Horizontally scalable
DB Scaling
- Sharding by:
hash(short_code)
Cache Scaling
- Redis cluster
6.5 Hot Key Handling
Problem:
- Viral links → extreme traffic
Solution:
- CDN absorbs majority
- Redis handles remaining
- Replication for hot keys
7. Additional Considerations
7.1 Burst Traffic Handling
- CDN absorbs sudden spikes
- Redis handles high QPS
- Backend protected from overload
7.2 Cache Miss Handling
- Redis miss → DB lookup
- Populate cache after read
7.3 Degraded Mode
Case 1: Redis Down
- Direct DB reads (higher latency)
Case 2: DB Down
- Serve from cache if available
Case 3: Full Failure
- Graceful degradation (temporary errors)
7.4 Expiration Handling
- TTL on DB + Redis
- Background cleanup jobs
7.5 Analytics
- Async logging
- Stream processing (Kafka)
7.6 Security
- Prevent abuse:
- Rate limiting
- Spam detection
🏁 Final Summary
- CDN + Redis caching ensures ultra-low latency
- Base62 encoding ensures compact unique URLs
- Distributed DB + sharding ensures scalability
- Stateless services ensure horizontal scaling
- Multi-layer caching handles extreme read load