Practical Design Examples 1
Practical Design Examples 1¶
Difficulty: ββββ
Overview¶
In this chapter, we design three systems that frequently appear in system design interviews: URL Shortener, Pastebin, and Rate Limiter. Each example follows the sequence of requirements definition, capacity estimation, high-level design, and detailed design.
Table of Contents¶
1. URL Shortener¶
1.1 Requirements Definition¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Functional Requirements β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Core Features: β
β 1. URL Shortening: Long URL β Short URL generation β
β 2. URL Redirection: Short URL β Redirect to original URL β
β β
β Additional Features: β
β 3. Custom short URLs (optional) β
β 4. URL expiration time setting β
β 5. Click analytics/statistics β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Non-Functional Requirements β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β - High availability: 99.9% uptime β
β - Low latency: Redirection < 100ms β
β - Scalability: Store hundreds of millions of URLs β
β - Security: Unpredictable short URLs β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1.2 Capacity Estimation¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Capacity Estimation (Back-of-envelope) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Assumptions: β
β - Monthly new URLs: 100M (100 million) β
β - Read/Write ratio: 100:1 β
β - URL retention period: 5 years β
β - Average URL length: 100 bytes β
β β
β Calculations: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Write QPS: β β
β β 100M / 30 days / 24 hours / 3600 seconds β 40 writes/sec β β
β β β β
β β Read QPS: β β
β β 40 * 100 = 4,000 reads/sec β β
β β β β
β β Total URLs over 5 years: β β
β β 100M * 12 months * 5 years = 6B (6 billion) β β
β β β β
β β Storage capacity: β β
β β 6B * (7 bytes short + 100 bytes long) β 640GB β β
β β β β
β β Bandwidth: β β
β β 4,000 reads/sec * 500 bytes = 2 MB/sec β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Determining Short URL Length: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Base62: [a-zA-Z0-9] = 62 characters β β
β β β β
β β 6 characters: 62^6 = 56.8 billion (sufficient!) β β
β β 7 characters: 62^7 = 3.5 trillion β β
β β β β
β β β Use 7 characters (with buffer) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1.3 High-Level Design¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β System Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Client β β
β β β β β
β β βΌ β β
β β βββββββββββββββββββ β β
β β β Load Balancer β β β
β β ββββββββββ¬βββββββββ β β
β β β β β
β β βββββββ΄ββββββ β β
β β βΌ βΌ β β
β β βββββββββββ βββββββββββ β β
β β βAPI Srv 1β βAPI Srv 2β ... β β
β β ββββββ¬βββββ ββββββ¬βββββ β β
β β β β β β
β β βββββββ¬ββββββ β β
β β β β β
β β βββββββ΄ββββββ β β
β β βΌ βΌ β β
β β βββββββββββ βββββββββββββββ β β
β β β Cache β β Database β β β
β β β (Redis) β β (MySQL/Mongo)β β β
β β βββββββββββ βββββββββββββββ β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β API Design: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β POST /api/shorten β β
β β Body: { "long_url": "https://...", "expiry": "2024-12-31" } β β
β β Response: { "short_url": "https://tinyurl.com/abc123" } β β
β β β β
β β GET /{short_code} β β
β β Response: 301 Redirect to original URL β β
β β β β
β β GET /api/stats/{short_code} β β
β β Response: { "clicks": 1234, "created_at": "..." } β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1.4 Detailed Design: Short URL Generation¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Method 1: Hash + Collision Handling β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β long_url = "https://example.com/very/long/path" β β
β β β β β
β β βΌ β β
β β MD5(long_url) = "e4d909c290d0fb1ca068ffaddf22cbd0" β β
β β β β β
β β βΌ β β
β β Base62(first 43 bits) = "abc123d" β β
β β β β β
β β βΌ β β
β β Check collision β β
β β β β β
β β ββββββ΄βββββ β β
β β β β β β
β β βΌ βΌ β β
β β None Exists β β
β β β β β β
β β β Add salt to long_url β β
β β β Re-hash β β
β β β β β β
β β ββββββ¬βββββ β β
β β βΌ β β
β β Store β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Pros: Same URL β Same short URL (cache efficiency) β
β Cons: Collision handling logic required β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Method 2: ID Generator (Recommended) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β ID Generator β β β
β β β β β β
β β β Method A: Auto-increment (single DB) β β β
β β β - Simple but SPOF β β β
β β β β β β
β β β Method B: Range-based β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β ZooKeeper/etcd β β β β
β β β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β β β
β β β β β Server 1: 1-1,000,000 β β β β β
β β β β β Server 2: 1,000,001-2,000,000 β β β β β
β β β β β Server 3: 2,000,001-3,000,000 β β β β β
β β β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β β β
β β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β β β
β β β Method C: Snowflake ID β β β
β β β [timestamp: 41bits][machine: 10bits][sequence: 12bits] β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β βΌ β β
β β ID = 123456789 β β
β β β β β
β β βΌ β β
β β Base62(123456789) = "8M0kX" β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Pros: No collisions, easy to scale β
β Cons: Same URL gets different short URLs β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1.5 Detailed Design: Redirection¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Redirection Flow β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β GET /abc123 β
β β β
β βΌ β
β βββββββββββββββ β
β β Load Balancerβ β
β ββββββββ¬βββββββ β
β β β
β βΌ β
β βββββββββββββββ βββββββββββββββ β
β β API Server ββββββΊβ Redis Cache β β
β ββββββββ¬βββββββ ββββββββ¬βββββββ β
β β β β
β β Cache hit? β
β β β β
β β ββββββββ΄βββββββ β
β β β β β
β β Yes No β
β β β β β
β β β ββββββββΌβββββββ β
β β β β Database β β
β β β ββββββββ¬βββββββ β
β β β β β
β β β Store in cache β
β β β β β
β β ββββββββ¬βββββββ β
β β β β
β βΌ βΌ β
β βββββββββββββββββββββββββββββββββββββββ β
β β HTTP 301 (permanent) or 302 (temp) β β
β β Location: https://original-url.com β β
β βββββββββββββββββββββββββββββββββββββββ β
β β
β 301 vs 302: β
β - 301: Browser caching β Reduced server load, inaccurate stats β
β - 302: Every request hits server β Accurate stats, higher load β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1.6 Database Schema¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Database Design β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β urls table: β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Column Type Description β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β id BIGINT PK, auto-increment β β
β β short_code VARCHAR(7) UK, indexed β β
β β long_url VARCHAR(2048) Original URL β β
β β user_id BIGINT FK, nullable β β
β β created_at DATETIME Creation time β β
β β expires_at DATETIME Expiration time, nullable β β
β β click_count BIGINT Click count β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Indexes: β
β - PRIMARY KEY (id) β
β - UNIQUE INDEX idx_short_code (short_code) β
β - INDEX idx_user_id (user_id) β
β - INDEX idx_expires_at (expires_at) β
β β
β click_analytics table (optional): β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β url_id BIGINT FK β β
β β clicked_at DATETIME Click time β β
β β ip_address VARCHAR(45) IPv6 support β β
β β user_agent VARCHAR(255) Browser info β β
β β referrer VARCHAR(2048) Traffic source β β
β β country VARCHAR(2) Country code β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2. Pastebin¶
2.1 Requirements Definition¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Functional Requirements β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Core Features: β
β 1. Paste text and generate URL β
β 2. Retrieve text via URL β
β 3. Set expiration time β
β β
β Additional Features: β
β 4. Syntax highlighting β
β 5. Password protection β
β 6. One-time view (delete after reading) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Constraints β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β - Maximum text size: 10MB β
β - Default expiration: 30 days β
β - Anonymous users allowed β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2.2 Capacity Estimation¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Capacity Estimation β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Assumptions: β
β - Daily new pastes: 1M β
β - Read/Write ratio: 5:1 β
β - Average text size: 10KB β
β - Retention period: 1 year β
β β
β Calculations: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Write QPS: 1M / 86400 β 12 writes/sec β β
β β Read QPS: 12 * 5 = 60 reads/sec β β
β β β β
β β Daily storage: 1M * 10KB = 10GB β β
β β Annual storage: 10GB * 365 = 3.65TB β β
β β β β
β β Bandwidth: β β
β β - Write: 12 * 10KB = 120KB/sec β β
β β - Read: 60 * 10KB = 600KB/sec β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2.3 High-Level Design¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β System Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Client β β
β β β β β
β β βΌ β β
β β βββββββββββββββββββ β β
β β β Load Balancer β β β
β β ββββββββββ¬βββββββββ β β
β β β β β
β β βββββββ΄ββββββ β β
β β βΌ βΌ β β
β β βββββββββββ βββββββββββ β β
β β βAPI Srv 1β βAPI Srv 2β β β
β β ββββββ¬βββββ ββββββ¬βββββ β β
β β β β β β
β β βββββββ¬ββββββ β β
β β β β β
β β ββββββββββΌβββββββββ β β
β β βΌ βΌ βΌ β β
β β ββββββ βββββββββ ββββββββββββββββ β β
β β βCacheβ βMetaDB β βObject Storageβ β β
β β βRedisβ βMySQL β βS3/MinIO β β β
β β ββββββ βββββββββ ββββββββββββββββ β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Storage Strategy: β
β - Metadata (ID, created_at, expires_at): MySQL β
β - Actual text content: Object Storage (S3) β
β - Frequently accessed text: Redis cache β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2.4 Detailed Design: Storage Strategy¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Data Storage Flow β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Text Storage: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β POST /api/paste β β
β β { "content": "...", "expires_in": "7d" } β β
β β β β β
β β βΌ β β
β β ββββββββββββββββββββββ β β
β β β 1. Generate ID β (same approach as URL shortener) β β
β β β β paste_abc123 β β β
β β βββββββββββ¬βββββββββββ β β
β β β β β
β β βΌ β β
β β ββββββββββββββββββββββ βββββββββββββββββββββββ β β
β β β 2. Store content ββββββΊβ Object Storage β β β
β β β Apply compress β β Key: paste_abc123 β β β
β β β (gzip) β β Value: [gzipped] β β β
β β βββββββββββ¬βββββββββββ βββββββββββββββββββββββ β β
β β β β β
β β βΌ β β
β β ββββββββββββββββββββββ βββββββββββββββββββββββ β β
β β β 3. Store metadata ββββββΊβ MySQL β β β
β β β (atomic) β β id, created_at, β β β
β β β β β expires_at, size β β β
β β βββββββββββ¬βββββββββββ βββββββββββββββββββββββ β β
β β β β β
β β βΌ β β
β β Response: { "url": "https://paste.io/abc123" } β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Caching Strategy: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β - Cache only popular pastes (based on view count) β β
β β - LRU policy β β
β β - Cache size: 20% of storage (approximately 700GB) β β
β β - TTL: 1 hour (frequent refresh) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2.5 Expiration Policy¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Expired Data Cleanup β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Method 1: Lazy Deletion β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β GET /abc123 β β
β β β β β
β β βΌ β β
β β expires_at < now()? β β
β β β β β
β β ββββββ΄βββββ β β
β β β β β β
β β Yes No β β
β β β β β β
β β 404 Return β β
β β + Add to deletion queue β β
β β β β
β β Pros: Simple implementation, immediate β β
β β Cons: Unaccessed data remains β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Method 2: Background Cleanup β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Cron Job (hourly): β β
β β β β
β β SELECT id, storage_key β β
β β FROM pastes β β
β β WHERE expires_at < NOW() β β
β β LIMIT 1000; β β
β β β β
β β for each expired: β β
β β 1. Delete from Object Storage β β
β β 2. Delete from MySQL β β
β β 3. Invalidate Cache β β
β β β β
β β Pros: Reclaims storage space β β
β β Cons: Avoid peak hours β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Recommended: Combine both methods β
β - Lazy: Immediate expiration handling β
β - Background: Regular cleanup to reclaim storage β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3. Rate Limiter¶
3.1 Requirements Definition¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Functional Requirements β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Core Features: β
β 1. Request limiting: By IP, user, API key β
β 2. Various time windows: Per second, minute, hour β
β 3. Return 429 when exceeded β
β β
β Non-Functional Requirements: β
β - Distributed environment support β
β - Low latency (checked on every API call) β
β - High availability β
β - Accuracy (prevent race conditions) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3.2 Algorithm Comparison¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Rate Limiting Algorithms β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. Token Bucket β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β βββββββββββββββββββββββββββββββββββββββββ β β
β β β Bucket β β β
β β β Capacity: 10 tokens β β β
β β β βββββ¬ββββ¬ββββ¬ββββ¬ββββ¬ββββ¬ββββ β β Token added β β
β β β β β β β β β β β β β β β β β (1/sec) β β
β β β βββββ΄ββββ΄ββββ΄ββββ΄ββββ΄ββββ΄ββββ β β β
β β β β β β β
β β ββββββββββΌββββββββββββββββββββββββββββββββ β β
β β β β β
β β βΌ Token consumed on request β β
β β βββββββββββ β β
β β β Request β β β
β β βββββββββββ β β
β β β β
β β Characteristics: β β
β β - Allows bursts (if bucket has tokens) β β
β β - Tokens refilled at constant rate β β
β β - Memory efficient β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β 2. Leaky Bucket β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β β Request inflow β β
β β βΌ β β
β β βββββββββββ β β
β β β Queue β β Reject if queue full β β
β β β (FIFO) β β β
β β ββββββ¬βββββ β β
β β β β β
β β β Leak (process) at constant rate β β
β β βΌ β β
β β βββββββββββ β β
β β β Process β β β
β β βββββββββββ β β
β β β β
β β Characteristics: β β
β β - Guarantees constant processing rate β β
β β - Smooths out bursts β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β 3. Fixed Window β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Time βββββββββββββββββββββββββββββββββββββββββββββββββββββββΊ β β
β β β β
β β ββββ Window 1 βββΊββββ Window 2 βββΊββββ Window 3 βββΊβ β β
β β β (limit: 5) β (limit: 5) β (limit: 5) β β β
β β β βββββ β ββ β ββββ β β β
β β β count: 5 β count: 2 β count: 4 β β β
β β β β
β β Problem: Bursts at window boundaries β β
β β 5 at end of Window 1 + 5 at start of Window 2 = 10! β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β 4. Sliding Window Log β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Store timestamp of each request: β β
β β [12:00:01, 12:00:15, 12:00:32, 12:00:45, 12:01:02, ...] β β
β β β β
β β Count requests within current time - 1 minute β β
β β β β
β β Pros: Accurate β β
β β Cons: High memory usage β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β 5. Sliding Window Counter (Recommended) β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Weighted average of current + previous window β β
β β β β
β β Previous window: 3 requests β β
β β Current window: 5 requests β β
β β Current position: 70% into window β β
β β β β
β β Estimated count: 3 * 0.3 + 5 = 5.9 β β
β β β β
β β Pros: Memory efficient + accurate β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3.3 High-Level Design¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Rate Limiter Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Deployed as middleware (API Gateway or service level) β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Client β β
β β β β β
β β βΌ β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β API Gateway β β β
β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β
β β β β Rate Limiter Middleware β β β β
β β β β β β β β
β β β β ββββββββββββββ ββββββββββββββββββββββββββββββ β β β β
β β β β β Rate Rules β β Redis Cluster β β β β β
β β β β β βββββββΊβ βββββββ βββββββ βββββββ β β β β β
β β β β β - 100/min β β βNode1β βNode2β βNode3β β β β β β
β β β β β - 1000/hr β β βββββββ βββββββ βββββββ β β β β β
β β β β ββββββββββββββ ββββββββββββββββββββββββββββββ β β β β
β β β β β β β β
β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β β Allow β Deny β β
β β βΌ βΌ β β
β β βββββββββββββββββββ βββββββββββββββββββββββ β β
β β β Backend API β β 429 Too Many β β β
β β β Servers β β Requests β β β
β β βββββββββββββββββββ β Retry-After: 60 β β β
β β βββββββββββββββββββββββ β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3.4 Redis Implementation: Token Bucket¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Redis Token Bucket Implementation β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Data Structure: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Key: rate_limit:{user_id} β β
β β Value: HASH β β
β β - tokens: current token count β β
β β - last_refill: last refill time β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Lua Script (atomic execution): β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β local key = KEYS[1] β β
β β local capacity = tonumber(ARGV[1]) -- bucket capacity β β
β β local refill_rate = tonumber(ARGV[2]) -- tokens per second β β
β β local now = tonumber(ARGV[3]) -- current time (ms) β β
β β local requested = tonumber(ARGV[4]) -- requested tokens β β
β β β β
β β local bucket = redis.call('HGETALL', key) β β
β β local tokens = capacity β β
β β local last_refill = now β β
β β β β
β β if #bucket > 0 then β β
β β tokens = tonumber(bucket[2]) β β
β β last_refill = tonumber(bucket[4]) β β
β β end β β
β β β β
β β -- Refill tokens β β
β β local elapsed = (now - last_refill) / 1000 β β
β β local refill = elapsed * refill_rate β β
β β tokens = math.min(capacity, tokens + refill) β β
β β β β
β β -- Process request β β
β β local allowed = 0 β β
β β if tokens >= requested then β β
β β tokens = tokens - requested β β
β β allowed = 1 β β
β β end β β
β β β β
β β redis.call('HSET', key, 'tokens', tokens, 'last_refill', now) β β
β β redis.call('EXPIRE', key, capacity / refill_rate * 2) β β
β β β β
β β return {allowed, tokens} β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
3.5 Distributed Environment Considerations¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Distributed Rate Limiter Issues β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Problem 1: Race Condition β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Server 1: GET counter β 99 β β
β β Server 2: GET counter β 99 β β
β β Server 1: SET counter β 100 (allowed) β β
β β Server 2: SET counter β 100 (allowed!) β Limit exceeded! β β
β β β β
β β Solution: Atomic execution with Lua Script β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Problem 2: Redis Cluster Sync Delay β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Solutions: β β
β β - Same user goes to same Redis node (Consistent Hashing) β β
β β - Or tolerate some margin of error β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Problem 3: Redis Failure β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Fallback strategies: β β
β β 1. Allow all requests (availability priority) β β
β β 2. Use local cache (reduced accuracy) β β
β β 3. Deny all requests (security priority) β β
β β β β
β β Recommended: Choose based on service characteristics β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Rate Limit Rules Configuration: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β { β β
β β "rules": [ β β
β β { β β
β β "key": "user:{user_id}", β β
β β "limit": 100, β β
β β "window": "60s" β β
β β }, β β
β β { β β
β β "key": "ip:{client_ip}", β β
β β "limit": 1000, β β
β β "window": "1h" β β
β β }, β β
β β { β β
β β "key": "api:{api_key}:/expensive-endpoint", β β
β β "limit": 10, β β
β β "window": "1m" β β
β β } β β
β β ] β β
β β } β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
4. Practice Problems¶
Exercise 1: URL Shortener Extension¶
Design extensions to the URL shortener with the following features: - Redirect to different URLs based on country - A/B testing support (50% to URL-A, 50% to URL-B) - Dashboard for analyzing 1 million clicks per day
Exercise 2: Pastebin Security¶
Design to meet the following security requirements: - Password-protected pastes - Burn after read (auto-delete after viewing) - Client-side encryption option
Exercise 3: Dynamic Rate Limiting¶
Design a Rate Limiter with the following requirements: - Different limits per user tier (free/paid/enterprise) - Automatic adjustment during peak hours - Granular limits per API endpoint
Next Steps¶
In 18_Design_Example_2.md, let's design News Feed, Chat System, and Notification System!
References¶
- "System Design Interview" - Alex Xu
- "Designing Data-Intensive Applications" - Martin Kleppmann
- bit.ly, TinyURL Architecture Analysis
- Stripe Rate Limiting Best Practices
- GitHub API Rate Limiting