Designing Real SystemsLesson 5.1
How to design a URL shortener like bit.ly
base62 encoding, ID generation, redirect architecture, analytics tracking, custom aliases, database schema design, read-heavy optimization
Requirements
URL shortener: classic interview question. Deceptively simple. The depth is in ID generation and redirect latency optimization.
Core Flows
- Write: POST /shorten → generate short ID → store (shortId, longUrl, createdAt) → return short URL
- Read: GET /abc123 → lookup longUrl → HTTP 301/302 redirect
ID Generation: Base62 Encoding
import string
CHARS = string.ascii_letters + string.digits # 62 chars
def encode(num):
result = []
while num:
result.append(CHARS[num % 62])
num //= 62
return ''.join(reversed(result))
# encode(125000000) -> '5lnM' (7-char IDs support 62^7 ~ 3.5 trillion URLs)Database Schema
CREATE TABLE urls (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
short_id VARCHAR(10) UNIQUE,
long_url TEXT NOT NULL,
user_id BIGINT,
created_at TIMESTAMP,
expires_at TIMESTAMP,
click_count BIGINT DEFAULT 0
);Read Optimization
Reads massively outnumber writes. Cache short_id → long_url in Redis with TTL 24h. Cache hit: return redirect in <1ms. Cache miss: DB lookup, populate cache, redirect. Use HTTP 301 (permanent) for analytics bypass, HTTP 302 (temporary) if you want to track every click server-side.
