URL Shortener
1. Clarify Requirements
Before jumping into architecture, we need to pin things down:
Functional requirements
- Shorten a long URL → return a short URL
- Redirect short URL → original URL
- Optional:
- Custom aliases?
- Expiration time?
- Analytics (click count, geo, etc.)?
Non-functional requirements
- High availability (redirects must work almost always)
- Low latency (redirects should be ~10–50ms)
- Massive scale (millions/billions of URLs)
- Read-heavy system (redirects >> writes)
Let’s assume:
- 100M new URLs/day
- 1000:1 read/write ratio
2. High-Level Design
At a high level, the system has two main flows:
flowchart LR U[User] --> CDN[CDN / Edge] CDN --> LB[Load Balancer] LB --> APP[App Servers<br/>stateless] APP --> RC[(Redis Cache<br/>hot short codes)] APP --> DB[(Sharded NoSQL<br/>short_code → long_url)] APP --> IDG[Distributed ID Generator<br/>Snowflake + Base62]
A. Write path (shorten URL)
- User submits long URL
- Generate short code
- Store mapping:
short_code → long_url - Return short URL
B. Read path (redirect)
- User hits short URL
- Lookup short_code
- Redirect (HTTP 301/302) to long URL
3. Core Components
1. API Layer
POST /shortenGET /{short_code}→ redirect
2. Application Servers
Stateless, horizontally scalable
3. Database
Stores mapping:
short_code (PK) | long_url | created_at | expiration | user_id4. Cache (Redis)
- Cache hot URLs
- Reduce DB load on redirects
4. Short Code Generation (Critical Design Choice)
This is where most of the complexity lies.
Option A: Auto-increment ID + Base62 encoding
- DB generates unique ID
- Convert ID → Base62 (e.g.,
aZ9kL)
Pros
- Simple
- Guaranteed uniqueness
- Compact
Cons
- DB becomes bottleneck for ID generation at scale
Option B: Distributed ID generation (better)
Use something like:
- Snowflake IDs (Twitter style)
- Or pre-allocated ID ranges
Flow:
- Generate unique ID in app layer
- Encode to Base62
Pros
- Scales horizontally
- No central bottleneck
Option C: Hash of URL (not ideal alone)
- Hash long URL → take first N chars
Problems
- Collisions
- Need collision resolution anyway
Best practical choice: distributed ID generation + Base62 encoding. It scales horizontally, guarantees uniqueness, and keeps codes short.
5. Database Design
Schema (simple version)
Table: url_mapping
short_code (PK, indexed)
long_url
created_at
expiration_at (nullable)Scaling the DB
At large scale:
- Use sharding by
short_code - Use NoSQL (e.g., DynamoDB, Cassandra) for:
- High write throughput
- Horizontal scaling
6. Read Optimization (Critical)
Reads dominate, so optimize heavily:
Cache layer
Redis:
key: short_code value: long_urlCache hot entries
Flow:
- Check cache
- If miss → DB
- Populate cache
sequenceDiagram
participant U as User
participant A as App Server
participant R as Redis
participant D as Database
U->>A: GET /aZ9kL
A->>R: GET aZ9kL
alt cache hit
R-->>A: long_url
else cache miss
R-->>A: nil
A->>D: SELECT long_url WHERE short_code = 'aZ9kL'
D-->>A: long_url
A->>R: SET aZ9kL → long_url (TTL)
end
A-->>U: 302 Redirect → long_url7. Handling Scale
Let’s sanity-check:
Storage
100M URLs/day → ~36B/year
If each record ≈ 200 bytes: → ~7.2 TB/year
Verdict: totally manageable with sharding.
Traffic
If 1000:1 read/write:
- Writes: 100M/day ≈ 1.1K/sec
- Reads: 1B/day ≈ 11.5K/sec
Peak could be 10x:
- ~100K reads/sec
This needs:
- CDN (optional)
- Aggressive caching
8. CDN Optimization (Advanced)
You can cache redirects at edge:
- CDN stores: short URL → redirect response
Benefit
- Ultra-low latency globally
- Offloads origin servers
9. Reliability & Edge Cases
Expiration
- TTL field
- Lazy deletion or background cleanup
Custom aliases
- Need uniqueness check
- Slightly slower writes
Abuse prevention
- Rate limiting
- Spam detection
10. Trade-offs to Think About
Here’s where interviews go deeper:
Consistency vs availability
- Is eventual consistency acceptable? (Usually yes)
Cache invalidation
- What if URL changes? (rare)
Hot keys
- Viral links → Redis hotspots
ID generation
- Centralized vs distributed
11. Deep Dive (Let’s Go Further)
If you want to push this toward senior-level discussion, we can zoom into one area:
- Designing a Snowflake ID generator
- Sharding strategy (range vs hash)
- Handling hot URLs at scale
- Analytics pipeline (Kafka + OLAP)
- Designing custom aliases at scale