Design Bit.ly
Design Bit.ly
URL shortener blueprint covering requirements, APIs, scale story, and counter design.
Understanding the Problem
Bit.ly is a URL shortener that converts long URLs into short, shareable links. It is also a friendly starter prompt for system design interviews.
Treat this as a guided walkthrough for junior candidates: requirements → APIs → high-level architecture → deep dives.
Functional Requirements
Focus on the core; everything else is “below the line.”
- ▹Submit a long URL and receive a short URL.
- ▹Optional custom alias.
- ▹Optional expiration date.
- ▹Short URL always resolves to the original URL.
- ▹Below the line: accounts, analytics, abuse workflows.
Non-Functional Requirements
Benchmarks drive caching, storage, and availability choices.
- ▹Uniqueness for short codes; no collisions.
- ▹Redirect latency < 100 ms.
- ▹Availability target 99.99% (prefer availability over strict consistency).
- ▹Scale to 1B URLs, 100M DAU, ~1000:1 read/write ratio.
Core Entities
Long URL, Short URL, User. Expand later when drawing tables/indexes.
API Contracts
Map each requirement to a REST endpoint.
POST /urls
{
"long_url": "https://example.com/very/long",
"custom_alias": "optional",
"expiration_date": "optional"
}
GET /{short_code} -> HTTP 302 redirectHigh-Level Design
Create flow: Client → Primary Service → Validation + short-code generation → DB.
Read flow: Client → Service → Cache lookup → DB fallback → HTTP 302.
Use 302 to retain control, update destinations, and collect metrics.
Potential Deep Dives
- ▹Short-code generation strategies (counter + base62, hashids, UUID + collision check).
- ▹Caching strategy for read-heavy workloads; avoid full table scans.
- ▹Scale reads/writes independently; shard DB only when necessary.
Scaling Writes + Counter Service
Reads dominate, but writes still need a globally unique counter.
Use Redis for atomic increments or batch allocations; replicate for HA.