forgecommandline 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- forgecli/__init__.py +2 -0
- forgecli/ads.py +322 -0
- forgecli/agent.py +1093 -0
- forgecli/art.py +574 -0
- forgecli/attach.py +246 -0
- forgecli/brief.py +215 -0
- forgecli/browsercheck.py +99 -0
- forgecli/checkpoints.py +81 -0
- forgecli/city.py +833 -0
- forgecli/cli.py +1668 -0
- forgecli/config.py +194 -0
- forgecli/courier.py +177 -0
- forgecli/courier_data.py +164 -0
- forgecli/courier_hd.py +431 -0
- forgecli/courier_hd_data.bin +0 -0
- forgecli/courier_hd_data.py +19 -0
- forgecli/ghlogin.py +76 -0
- forgecli/github.py +54 -0
- forgecli/guards.py +403 -0
- forgecli/hooks.py +50 -0
- forgecli/httpapi.py +434 -0
- forgecli/images.py +110 -0
- forgecli/keys.py +152 -0
- forgecli/keyvault.py +320 -0
- forgecli/mcp.py +674 -0
- forgecli/memory.py +42 -0
- forgecli/openapi.py +331 -0
- forgecli/parallel.py +308 -0
- forgecli/prices.py +72 -0
- forgecli/procs.py +144 -0
- forgecli/providers.py +758 -0
- forgecli/quality.py +192 -0
- forgecli/repomap.py +78 -0
- forgecli/roster.py +227 -0
- forgecli/safety.py +93 -0
- forgecli/sandbox.py +83 -0
- forgecli/sessions.py +97 -0
- forgecli/skills.py +446 -0
- forgecli/tools.py +1184 -0
- forgecli/ui.py +860 -0
- forgecli/worktrees.py +79 -0
- forgecommandline-0.8.0.data/data/skills/commit/SKILL.md +14 -0
- forgecommandline-0.8.0.data/data/skills/debug/SKILL.md +17 -0
- forgecommandline-0.8.0.data/data/skills/explain/SKILL.md +14 -0
- forgecommandline-0.8.0.data/data/skills/init/SKILL.md +19 -0
- forgecommandline-0.8.0.data/data/skills/library/LICENSES/agent-skills-MIT.txt +21 -0
- forgecommandline-0.8.0.data/data/skills/library/LICENSES/wondelai-MIT.txt +23 -0
- forgecommandline-0.8.0.data/data/skills/library/README.md +9 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/accessibility-checklist.md +160 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/definition-of-done.md +67 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/observability-checklist.md +92 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/orchestration-patterns.md +370 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/performance-checklist.md +238 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/security-checklist.md +248 -0
- forgecommandline-0.8.0.data/data/skills/library/_references/testing-patterns.md +235 -0
- forgecommandline-0.8.0.data/data/skills/library/api-and-interface-design/SKILL.md +367 -0
- forgecommandline-0.8.0.data/data/skills/library/architecture-optimization/SKILL.md +279 -0
- forgecommandline-0.8.0.data/data/skills/library/architecture-optimization/references/artifact-templates.md +157 -0
- forgecommandline-0.8.0.data/data/skills/library/architecture-optimization/references/methods.md +87 -0
- forgecommandline-0.8.0.data/data/skills/library/awwwards-tier-web-application/SKILL.md +877 -0
- forgecommandline-0.8.0.data/data/skills/library/browser-testing-with-devtools/SKILL.md +317 -0
- forgecommandline-0.8.0.data/data/skills/library/ci-cd-and-automation/SKILL.md +390 -0
- forgecommandline-0.8.0.data/data/skills/library/code-review-and-quality/SKILL.md +398 -0
- forgecommandline-0.8.0.data/data/skills/library/code-simplification/SKILL.md +331 -0
- forgecommandline-0.8.0.data/data/skills/library/constraint-driven-development/SKILL.md +311 -0
- forgecommandline-0.8.0.data/data/skills/library/constraint-driven-development/references/floor-guard.md +182 -0
- forgecommandline-0.8.0.data/data/skills/library/context-engineering/SKILL.md +353 -0
- forgecommandline-0.8.0.data/data/skills/library/debugging-and-error-recovery/SKILL.md +300 -0
- forgecommandline-0.8.0.data/data/skills/library/deprecation-and-migration/SKILL.md +247 -0
- forgecommandline-0.8.0.data/data/skills/library/documentation-and-adrs/SKILL.md +297 -0
- forgecommandline-0.8.0.data/data/skills/library/doubt-driven-development/SKILL.md +243 -0
- forgecommandline-0.8.0.data/data/skills/library/frontend-ui-engineering/SKILL.md +340 -0
- forgecommandline-0.8.0.data/data/skills/library/git-workflow-and-versioning/SKILL.md +355 -0
- forgecommandline-0.8.0.data/data/skills/library/idea-refine/SKILL.md +193 -0
- forgecommandline-0.8.0.data/data/skills/library/idea-refine/examples.md +238 -0
- forgecommandline-0.8.0.data/data/skills/library/idea-refine/frameworks.md +99 -0
- forgecommandline-0.8.0.data/data/skills/library/idea-refine/refinement-criteria.md +113 -0
- forgecommandline-0.8.0.data/data/skills/library/idea-refine/scripts/idea-refine.sh +15 -0
- forgecommandline-0.8.0.data/data/skills/library/improve-code-quality/SKILL.md +275 -0
- forgecommandline-0.8.0.data/data/skills/library/improve-code-quality/references/artifact-templates.md +101 -0
- forgecommandline-0.8.0.data/data/skills/library/incremental-implementation/SKILL.md +249 -0
- forgecommandline-0.8.0.data/data/skills/library/interview-me/SKILL.md +235 -0
- forgecommandline-0.8.0.data/data/skills/library/observability-and-instrumentation/SKILL.md +238 -0
- forgecommandline-0.8.0.data/data/skills/library/performance-optimization/SKILL.md +267 -0
- forgecommandline-0.8.0.data/data/skills/library/performance-optimization/references/optimization-patterns.md +250 -0
- forgecommandline-0.8.0.data/data/skills/library/planning-and-task-breakdown/SKILL.md +257 -0
- forgecommandline-0.8.0.data/data/skills/library/remove-technical-debt/SKILL.md +203 -0
- forgecommandline-0.8.0.data/data/skills/library/remove-technical-debt/references/artifact-templates.md +79 -0
- forgecommandline-0.8.0.data/data/skills/library/security-and-hardening/SKILL.md +216 -0
- forgecommandline-0.8.0.data/data/skills/library/security-and-hardening/references/hardening-patterns.md +324 -0
- forgecommandline-0.8.0.data/data/skills/library/shipping-and-launch/SKILL.md +336 -0
- forgecommandline-0.8.0.data/data/skills/library/source-driven-development/SKILL.md +216 -0
- forgecommandline-0.8.0.data/data/skills/library/spec-driven-development/SKILL.md +259 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/SKILL.md +207 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/references/building-blocks.md +272 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/references/common-designs.md +257 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/references/database-scaling.md +295 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/references/estimation-numbers.md +250 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/references/four-step-process.md +286 -0
- forgecommandline-0.8.0.data/data/skills/library/system-design/references/reliability-operations.md +373 -0
- forgecommandline-0.8.0.data/data/skills/library/test-driven-development/SKILL.md +398 -0
- forgecommandline-0.8.0.data/data/skills/library/using-agent-skills/SKILL.md +192 -0
- forgecommandline-0.8.0.data/data/skills/review/SKILL.md +16 -0
- forgecommandline-0.8.0.data/data/skills/run/SKILL.md +17 -0
- forgecommandline-0.8.0.data/data/skills/security-review/SKILL.md +20 -0
- forgecommandline-0.8.0.data/data/skills/simplify/SKILL.md +18 -0
- forgecommandline-0.8.0.data/data/skills/test/SKILL.md +16 -0
- forgecommandline-0.8.0.data/data/skills/web-build/SKILL.md +25 -0
- forgecommandline-0.8.0.dist-info/METADATA +357 -0
- forgecommandline-0.8.0.dist-info/RECORD +113 -0
- forgecommandline-0.8.0.dist-info/WHEEL +5 -0
- forgecommandline-0.8.0.dist-info/entry_points.txt +2 -0
- forgecommandline-0.8.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Building Blocks of Scalable Systems
|
|
2
|
+
|
|
3
|
+
The core components used to assemble distributed systems. Each block solves a specific problem; knowing when and why to introduce each one is the foundation of system design.
|
|
4
|
+
|
|
5
|
+
## DNS (Domain Name System)
|
|
6
|
+
|
|
7
|
+
### What It Does
|
|
8
|
+
|
|
9
|
+
Translates human-readable domain names (example.com) into IP addresses (93.184.216.34). It is the first step in every web request.
|
|
10
|
+
|
|
11
|
+
### Key Concepts
|
|
12
|
+
|
|
13
|
+
- **A record:** Maps domain to IPv4 address
|
|
14
|
+
- **AAAA record:** Maps domain to IPv6 address
|
|
15
|
+
- **CNAME record:** Maps domain to another domain (aliasing)
|
|
16
|
+
- **NS record:** Delegates a subdomain to a nameserver
|
|
17
|
+
- **TTL (Time to Live):** How long DNS resolvers cache the result
|
|
18
|
+
|
|
19
|
+
### Design Implications
|
|
20
|
+
|
|
21
|
+
- DNS-based load balancing: return different IPs for the same domain (round-robin DNS)
|
|
22
|
+
- GeoDNS: return different IPs based on the client's geographic location
|
|
23
|
+
- Low TTL enables faster failover but increases DNS query load
|
|
24
|
+
- DNS propagation delay (minutes to hours) affects failover speed
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## CDN (Content Delivery Network)
|
|
29
|
+
|
|
30
|
+
### What It Does
|
|
31
|
+
|
|
32
|
+
Caches static and semi-static content at edge servers geographically close to users. Reduces latency and offloads origin servers.
|
|
33
|
+
|
|
34
|
+
### Types
|
|
35
|
+
|
|
36
|
+
| Type | What It Caches | Best For |
|
|
37
|
+
|------|---------------|----------|
|
|
38
|
+
| **Push CDN** | Content is uploaded proactively by origin | Small, rarely changing content (assets, firmware) |
|
|
39
|
+
| **Pull CDN** | Content is fetched from origin on first request, then cached | Large, frequently accessed content (images, videos, CSS/JS) |
|
|
40
|
+
|
|
41
|
+
### What to Put on a CDN
|
|
42
|
+
|
|
43
|
+
- Static assets: CSS, JavaScript, fonts, images, videos
|
|
44
|
+
- Semi-static content: user profile images, product images
|
|
45
|
+
- Pre-rendered pages: landing pages, marketing content
|
|
46
|
+
- API responses (with appropriate Cache-Control headers)
|
|
47
|
+
|
|
48
|
+
### What NOT to Put on a CDN
|
|
49
|
+
|
|
50
|
+
- Personalized content (user-specific data)
|
|
51
|
+
- Real-time data (stock prices, live scores)
|
|
52
|
+
- Content that changes every request
|
|
53
|
+
|
|
54
|
+
### Cache Invalidation
|
|
55
|
+
|
|
56
|
+
- **TTL-based:** Set expiration time; simple but content can be stale until TTL expires
|
|
57
|
+
- **Versioned URLs:** `style.v2.css` or `style.css?v=abc123`; instant invalidation, cache-friendly
|
|
58
|
+
- **Purge API:** Explicitly invalidate specific URLs; fast but requires operational tooling
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Load Balancers
|
|
63
|
+
|
|
64
|
+
### What They Do
|
|
65
|
+
|
|
66
|
+
Distribute incoming network traffic across multiple servers to ensure no single server is overwhelmed.
|
|
67
|
+
|
|
68
|
+
### L4 vs L7 Load Balancing
|
|
69
|
+
|
|
70
|
+
| Feature | L4 (Transport Layer) | L7 (Application Layer) |
|
|
71
|
+
|---------|---------------------|----------------------|
|
|
72
|
+
| **Operates on** | TCP/UDP packets | HTTP/HTTPS requests |
|
|
73
|
+
| **Speed** | Faster (less processing) | Slower (inspects content) |
|
|
74
|
+
| **Routing decisions** | IP address, port | URL path, headers, cookies, body |
|
|
75
|
+
| **SSL termination** | No (pass-through) | Yes (can decrypt and re-encrypt) |
|
|
76
|
+
| **Use cases** | High-throughput TCP services | Web apps, API routing, A/B testing |
|
|
77
|
+
|
|
78
|
+
### Load Balancing Algorithms
|
|
79
|
+
|
|
80
|
+
| Algorithm | How It Works | Best For |
|
|
81
|
+
|-----------|-------------|----------|
|
|
82
|
+
| **Round robin** | Rotate through servers sequentially | Homogeneous servers, even request complexity |
|
|
83
|
+
| **Weighted round robin** | Rotate with weights per server | Servers with different capacities |
|
|
84
|
+
| **Least connections** | Route to server with fewest active connections | Varying request durations |
|
|
85
|
+
| **IP hash** | Hash client IP to pick server | Session stickiness without cookies |
|
|
86
|
+
| **Consistent hashing** | Minimal redistribution when servers change | Cache servers, stateful routing |
|
|
87
|
+
|
|
88
|
+
### Health Checks
|
|
89
|
+
|
|
90
|
+
- **Active health checks:** Load balancer periodically pings each server (HTTP GET /health)
|
|
91
|
+
- **Passive health checks:** Monitor real traffic for errors (5xx responses, timeouts)
|
|
92
|
+
- **Unhealthy threshold:** Remove server after N consecutive failures
|
|
93
|
+
- **Recovery threshold:** Re-add server after M consecutive successes
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Reverse Proxy
|
|
98
|
+
|
|
99
|
+
### What It Does
|
|
100
|
+
|
|
101
|
+
Sits in front of web servers and forwards client requests. Provides a single entry point while hiding backend complexity.
|
|
102
|
+
|
|
103
|
+
### Benefits
|
|
104
|
+
|
|
105
|
+
- **Security:** Hides backend server IPs, terminates SSL, filters malicious requests
|
|
106
|
+
- **Caching:** Caches responses to reduce backend load
|
|
107
|
+
- **Compression:** Compresses responses before sending to clients
|
|
108
|
+
- **Rate limiting:** Controls request rate per client
|
|
109
|
+
- **SSL termination:** Handles HTTPS, backends communicate over HTTP internally
|
|
110
|
+
|
|
111
|
+
### Common Tools
|
|
112
|
+
|
|
113
|
+
- Nginx (most popular, also serves as load balancer)
|
|
114
|
+
- HAProxy (high-performance TCP/HTTP proxy)
|
|
115
|
+
- Envoy (modern, designed for microservices and service mesh)
|
|
116
|
+
- Traefik (auto-discovery, container-native)
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Caching
|
|
121
|
+
|
|
122
|
+
### Cache Layers
|
|
123
|
+
|
|
124
|
+
Caching can exist at every layer of the stack:
|
|
125
|
+
|
|
126
|
+
| Layer | What Is Cached | Tools | Latency |
|
|
127
|
+
|-------|---------------|-------|---------|
|
|
128
|
+
| **Client** | HTML, CSS, JS, images | Browser cache, local storage | ~0 ms |
|
|
129
|
+
| **CDN** | Static assets, pre-rendered pages | CloudFront, Cloudflare, Akamai | 5-50 ms |
|
|
130
|
+
| **Web server** | Full page responses | Nginx cache, Varnish | 1-5 ms |
|
|
131
|
+
| **Application** | Computed results, DB query results | Redis, Memcached | 1-5 ms |
|
|
132
|
+
| **Database** | Query plans, buffer pool | Built-in query cache | Varies |
|
|
133
|
+
|
|
134
|
+
### Cache Strategies
|
|
135
|
+
|
|
136
|
+
| Strategy | How It Works | Pros | Cons | Best For |
|
|
137
|
+
|----------|-------------|------|------|----------|
|
|
138
|
+
| **Cache-aside** | App checks cache; on miss, reads DB, writes to cache | Simple, app controls | Cache miss = two calls, possible stale data | General purpose, read-heavy |
|
|
139
|
+
| **Read-through** | Cache checks DB on miss automatically | Simpler app code | Cache library dependency | Read-heavy, standard lookups |
|
|
140
|
+
| **Write-through** | Write goes to cache AND DB synchronously | Cache always consistent | Write latency increased | Data that must be fresh |
|
|
141
|
+
| **Write-behind** | Write goes to cache; cache writes to DB asynchronously | Fast writes | Data loss risk if cache fails | High write throughput |
|
|
142
|
+
| **Refresh-ahead** | Cache proactively refreshes before TTL expires | Reduces cache miss latency | Wasted refreshes for unpopular keys | Frequently accessed hot data |
|
|
143
|
+
|
|
144
|
+
### Cache Invalidation Approaches
|
|
145
|
+
|
|
146
|
+
| Approach | How It Works | Tradeoff |
|
|
147
|
+
|----------|-------------|----------|
|
|
148
|
+
| **TTL (Time to Live)** | Entry expires after a set time | Simple but data can be stale |
|
|
149
|
+
| **Event-driven invalidation** | Write to DB triggers cache delete | Fresh data but coupling between writer and cache |
|
|
150
|
+
| **Version-based** | Cache key includes version number | Clean but requires version tracking |
|
|
151
|
+
| **Write-invalidate** | On write, delete the cache entry (next read re-populates) | Simple, avoids stale reads |
|
|
152
|
+
| **Write-update** | On write, update the cache entry with new value | Faster reads but more complex writes |
|
|
153
|
+
|
|
154
|
+
### Cache Eviction Policies
|
|
155
|
+
|
|
156
|
+
- **LRU (Least Recently Used):** Evict the entry not accessed for the longest time (most common)
|
|
157
|
+
- **LFU (Least Frequently Used):** Evict the entry accessed the fewest times
|
|
158
|
+
- **FIFO (First In, First Out):** Evict the oldest entry
|
|
159
|
+
- **Random:** Evict a random entry (surprisingly effective)
|
|
160
|
+
|
|
161
|
+
### Common Caching Problems
|
|
162
|
+
|
|
163
|
+
| Problem | Description | Solution |
|
|
164
|
+
|---------|------------|----------|
|
|
165
|
+
| **Cache stampede** | Many threads simultaneously miss cache and hit DB | Locking (only one thread fetches), request coalescing |
|
|
166
|
+
| **Hot key** | One key gets massive traffic | Replicate hot keys across multiple cache nodes |
|
|
167
|
+
| **Cache penetration** | Queries for non-existent data always miss | Cache null results with short TTL, use Bloom filter |
|
|
168
|
+
| **Cache warming** | Cold cache after restart causes DB overload | Pre-load popular keys at startup |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Message Queues
|
|
173
|
+
|
|
174
|
+
### What They Do
|
|
175
|
+
|
|
176
|
+
Decouple producers (senders) from consumers (processors) by placing an intermediary buffer between them. Producers write messages to the queue; consumers read and process them independently.
|
|
177
|
+
|
|
178
|
+
### Why Use Them
|
|
179
|
+
|
|
180
|
+
- **Decoupling:** Producer and consumer don't need to know about each other
|
|
181
|
+
- **Buffering:** Absorb traffic spikes without dropping requests
|
|
182
|
+
- **Async processing:** Return response to user immediately, process in background
|
|
183
|
+
- **Retry and dead-letter:** Failed messages can be retried or moved to a dead-letter queue
|
|
184
|
+
- **Fan-out:** One message can be consumed by multiple subscribers
|
|
185
|
+
|
|
186
|
+
### Queue vs Pub/Sub
|
|
187
|
+
|
|
188
|
+
| Feature | Queue (Point-to-Point) | Pub/Sub (Broadcast) |
|
|
189
|
+
|---------|----------------------|---------------------|
|
|
190
|
+
| **Consumers** | One consumer per message | All subscribers get every message |
|
|
191
|
+
| **Use case** | Task processing, job queues | Event notification, real-time feeds |
|
|
192
|
+
| **Examples** | SQS, RabbitMQ (queue mode) | SNS, Kafka (topics), Redis Pub/Sub |
|
|
193
|
+
|
|
194
|
+
### Common Tools
|
|
195
|
+
|
|
196
|
+
| Tool | Model | Strengths |
|
|
197
|
+
|------|-------|-----------|
|
|
198
|
+
| **Apache Kafka** | Distributed log, pub/sub | High throughput, message replay, ordering within partitions |
|
|
199
|
+
| **RabbitMQ** | AMQP broker, queue + pub/sub | Flexible routing, mature, good for complex workflows |
|
|
200
|
+
| **Amazon SQS** | Managed queue | Zero ops, scales automatically, at-least-once delivery |
|
|
201
|
+
| **Redis Streams** | In-memory stream | Very fast, consumer groups, simpler than Kafka |
|
|
202
|
+
|
|
203
|
+
### Message Delivery Guarantees
|
|
204
|
+
|
|
205
|
+
| Guarantee | Meaning | Tradeoff |
|
|
206
|
+
|-----------|---------|----------|
|
|
207
|
+
| **At-most-once** | Message delivered 0 or 1 times | Fast but messages can be lost |
|
|
208
|
+
| **At-least-once** | Message delivered 1 or more times | Reliable but consumers must handle duplicates |
|
|
209
|
+
| **Exactly-once** | Message delivered exactly 1 time | Ideal but expensive (requires idempotency or transactions) |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Consistent Hashing
|
|
214
|
+
|
|
215
|
+
### The Problem
|
|
216
|
+
|
|
217
|
+
Simple hash-based partitioning (key % N) breaks badly when N changes: almost all keys need to be remapped.
|
|
218
|
+
|
|
219
|
+
### How Consistent Hashing Works
|
|
220
|
+
|
|
221
|
+
1. Imagine a circular ring of hash values (0 to 2^32 - 1)
|
|
222
|
+
2. Each server is hashed to a point on the ring
|
|
223
|
+
3. Each key is hashed to a point on the ring
|
|
224
|
+
4. A key is assigned to the first server encountered clockwise from its position
|
|
225
|
+
|
|
226
|
+
### Why It Works
|
|
227
|
+
|
|
228
|
+
- When a server is added, only the keys between the new server and its predecessor need to move (~1/N of all keys)
|
|
229
|
+
- When a server is removed, only its keys need to be reassigned to the next server
|
|
230
|
+
- This is dramatically better than simple hashing where ~all keys move
|
|
231
|
+
|
|
232
|
+
### Virtual Nodes
|
|
233
|
+
|
|
234
|
+
Problem: with few servers, distribution can be very uneven.
|
|
235
|
+
Solution: map each physical server to multiple virtual nodes on the ring.
|
|
236
|
+
|
|
237
|
+
- Server A might be at positions 10, 90, 170, 250 on the ring
|
|
238
|
+
- Server B might be at positions 50, 130, 210, 290
|
|
239
|
+
- More virtual nodes = more even distribution (typically 100-200 per server)
|
|
240
|
+
|
|
241
|
+
### Applications
|
|
242
|
+
|
|
243
|
+
| Use Case | Why Consistent Hashing |
|
|
244
|
+
|----------|----------------------|
|
|
245
|
+
| **Distributed cache (Memcached, Redis cluster)** | Add/remove nodes without invalidating most cached data |
|
|
246
|
+
| **Database sharding** | Rebalance with minimal data movement |
|
|
247
|
+
| **CDN routing** | Route requests to nearest/appropriate edge server |
|
|
248
|
+
| **Load balancing** | Sticky sessions without storing session maps |
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Putting It All Together
|
|
253
|
+
|
|
254
|
+
A typical web-scale architecture layers these blocks:
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
Client -> DNS -> CDN (static) -> Load Balancer (L7)
|
|
258
|
+
-> Web Servers -> Application Servers
|
|
259
|
+
-> Cache (Redis) -> Database (Primary + Replicas)
|
|
260
|
+
-> Message Queue -> Worker Servers
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Design principle:** Start simple. Add each building block only when you hit the specific problem it solves:
|
|
264
|
+
1. Single server handles everything
|
|
265
|
+
2. Separate database from application server
|
|
266
|
+
3. Add load balancer and multiple app servers
|
|
267
|
+
4. Add cache for read-heavy paths
|
|
268
|
+
5. Add CDN for static assets
|
|
269
|
+
6. Add message queue for async processing
|
|
270
|
+
7. Add database replicas for read scaling
|
|
271
|
+
8. Shard database for write scaling
|
|
272
|
+
9. Add multiple datacenters for geographic distribution
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Common System Designs
|
|
2
|
+
|
|
3
|
+
Brief overviews of frequently encountered system designs. Each section covers the core requirements, key components, design decisions, and critical tradeoffs. Use these as starting templates that you adapt to specific requirements.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## URL Shortener
|
|
8
|
+
|
|
9
|
+
### Requirements
|
|
10
|
+
- Given a long URL, generate a short unique URL
|
|
11
|
+
- Given a short URL, redirect to the original URL
|
|
12
|
+
- Optional: custom short URLs, expiration, analytics
|
|
13
|
+
|
|
14
|
+
### Key Components
|
|
15
|
+
- **API service:** Accepts long URL, returns short URL; accepts short URL, returns redirect
|
|
16
|
+
- **ID generator:** Creates unique short codes (base62-encoded auto-increment or hash)
|
|
17
|
+
- **Key-value store:** Maps short code to long URL (Redis, DynamoDB, or Cassandra)
|
|
18
|
+
- **Analytics service:** Logs redirects for click tracking (async via message queue)
|
|
19
|
+
|
|
20
|
+
### Design Decisions
|
|
21
|
+
|
|
22
|
+
| Decision | Options | Recommendation |
|
|
23
|
+
|----------|---------|----------------|
|
|
24
|
+
| **ID generation** | Auto-increment + base62, hash (MD5/SHA), pre-generated IDs | Auto-increment + base62 for simplicity; pre-generated ranges for distributed |
|
|
25
|
+
| **Redirect type** | 301 (permanent) vs 302 (temporary) | 302 if you need analytics (browser doesn't cache); 301 for maximum performance |
|
|
26
|
+
| **Storage** | SQL vs NoSQL | NoSQL key-value (simple lookup, massive scale) |
|
|
27
|
+
| **Read optimization** | Cache layer | Cache-aside with Redis; short URLs follow power-law (few URLs get most traffic) |
|
|
28
|
+
|
|
29
|
+
### Scale Calculations (100M DAU)
|
|
30
|
+
- Write QPS: ~116 (10M new URLs/day)
|
|
31
|
+
- Read QPS: ~5,800 (500M redirects/day), peak ~29K
|
|
32
|
+
- Storage: ~1.1 TB/year (300 bytes per record, 10M/day, 10-year retention)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Rate Limiter
|
|
37
|
+
|
|
38
|
+
### Requirements
|
|
39
|
+
- Limit the number of requests a client can send in a time window
|
|
40
|
+
- Return 429 (Too Many Requests) when limit exceeded
|
|
41
|
+
- Must be low-latency (add minimal overhead to each request)
|
|
42
|
+
|
|
43
|
+
### Key Components
|
|
44
|
+
- **Rate limiter middleware:** Checks request against limits before routing to backend
|
|
45
|
+
- **Counter store:** Redis for atomic increment and TTL-based expiration
|
|
46
|
+
- **Configuration service:** Defines rules (100 requests/minute per API key)
|
|
47
|
+
|
|
48
|
+
### Algorithms
|
|
49
|
+
|
|
50
|
+
| Algorithm | How It Works | Pros | Cons |
|
|
51
|
+
|-----------|-------------|------|------|
|
|
52
|
+
| **Token bucket** | Bucket holds tokens; each request consumes one; bucket refills at fixed rate | Smooth, allows bursts up to bucket size | Requires per-client state |
|
|
53
|
+
| **Leaky bucket** | Requests enter a queue; processed at fixed rate | Very smooth output | Doesn't handle bursts well |
|
|
54
|
+
| **Fixed window** | Count requests in fixed time windows (e.g., each minute) | Simple | Spike at window boundary (2x burst) |
|
|
55
|
+
| **Sliding window log** | Store timestamp of each request; count within sliding window | Accurate | Memory-intensive (stores every timestamp) |
|
|
56
|
+
| **Sliding window counter** | Weighted combination of current and previous window | Good accuracy, low memory | Approximate (but close enough) |
|
|
57
|
+
|
|
58
|
+
### Design Decisions
|
|
59
|
+
|
|
60
|
+
| Decision | Options | Recommendation |
|
|
61
|
+
|----------|---------|----------------|
|
|
62
|
+
| **Where to rate-limit** | Client-side, API gateway, middleware, server-side | API gateway or middleware (centralized, before business logic) |
|
|
63
|
+
| **Counter storage** | Local memory, Redis, database | Redis (atomic operations, TTL, shared across servers) |
|
|
64
|
+
| **Distributed coordination** | Single Redis, Redis Cluster, local + sync | Redis Cluster for high availability |
|
|
65
|
+
| **Rate limit headers** | X-RateLimit-Remaining, X-RateLimit-Limit, Retry-After | Include all three; Retry-After is most important |
|
|
66
|
+
|
|
67
|
+
### Handling Exceeded Limits
|
|
68
|
+
- Return HTTP 429 with `Retry-After` header
|
|
69
|
+
- Optionally queue excess requests instead of rejecting
|
|
70
|
+
- Log rate-limited requests for monitoring (detect abuse patterns)
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Notification System
|
|
75
|
+
|
|
76
|
+
### Requirements
|
|
77
|
+
- Send push notifications, SMS, and email
|
|
78
|
+
- Support millions of users with different preferences
|
|
79
|
+
- Handle retry for failed deliveries
|
|
80
|
+
|
|
81
|
+
### Key Components
|
|
82
|
+
- **Notification service:** API to receive notification requests
|
|
83
|
+
- **User preference store:** Which channels each user has enabled
|
|
84
|
+
- **Template service:** Render notification content from templates
|
|
85
|
+
- **Delivery workers:** Per-channel workers (push, SMS, email)
|
|
86
|
+
- **Message queues:** One queue per channel for decoupling and retry
|
|
87
|
+
- **Delivery log:** Track sent, delivered, read status
|
|
88
|
+
|
|
89
|
+
### Design Decisions
|
|
90
|
+
- **Decouple with queues:** Separate queue per channel allows independent scaling and retry
|
|
91
|
+
- **Retry with exponential backoff:** Failed deliveries retry with increasing delay (1s, 2s, 4s, 8s...)
|
|
92
|
+
- **Rate limiting per user:** Prevent notification fatigue (max N notifications per hour)
|
|
93
|
+
- **Priority levels:** Urgent (password reset) vs normal (marketing) vs low (weekly digest)
|
|
94
|
+
- **Deduplication:** Idempotency key prevents sending the same notification twice
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## News Feed (Social Feed)
|
|
99
|
+
|
|
100
|
+
### Requirements
|
|
101
|
+
- Users follow other users
|
|
102
|
+
- When a user posts, followers see the post in their feed
|
|
103
|
+
- Feed is ordered by recency (or ranked by algorithm)
|
|
104
|
+
|
|
105
|
+
### Key Components
|
|
106
|
+
- **Post service:** Stores posts
|
|
107
|
+
- **Follow graph:** Stores who follows whom
|
|
108
|
+
- **Feed generation service:** Assembles personalized feeds
|
|
109
|
+
- **Feed cache:** Pre-computed feeds per user (Redis sorted sets)
|
|
110
|
+
- **Notification service:** Alerts followers of new posts
|
|
111
|
+
|
|
112
|
+
### The Core Tradeoff: Fanout Strategy
|
|
113
|
+
|
|
114
|
+
| Strategy | How It Works | Pros | Cons |
|
|
115
|
+
|----------|-------------|------|------|
|
|
116
|
+
| **Fanout-on-write (push)** | When user posts, write to every follower's feed cache | Fast reads (feed is pre-built) | Slow writes for celebrities, wastes storage for inactive users |
|
|
117
|
+
| **Fanout-on-read (pull)** | When user reads feed, fetch posts from all followed accounts | Fast writes, no wasted storage | Slow reads (must merge N sources), high read-time computation |
|
|
118
|
+
| **Hybrid** | Push for normal users, pull for celebrities | Balanced | More complex code |
|
|
119
|
+
|
|
120
|
+
### Hybrid Design (Recommended)
|
|
121
|
+
- Users with < 10K followers: fanout-on-write (pre-push to follower feeds)
|
|
122
|
+
- Users with > 10K followers: fanout-on-read (merge at read time)
|
|
123
|
+
- Feed cache: Redis sorted set per user, scored by timestamp, capped at ~1,000 entries
|
|
124
|
+
- Celebrity posts: fetch at read time and merge into the cached feed
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Chat System
|
|
129
|
+
|
|
130
|
+
### Requirements
|
|
131
|
+
- 1:1 and group messaging
|
|
132
|
+
- Real-time delivery (< 1 second latency)
|
|
133
|
+
- Message persistence and history
|
|
134
|
+
- Online/offline status (presence)
|
|
135
|
+
|
|
136
|
+
### Key Components
|
|
137
|
+
- **Connection service:** Manages WebSocket connections (stateful)
|
|
138
|
+
- **Message service:** Stores and retrieves messages
|
|
139
|
+
- **Presence service:** Tracks online/offline status
|
|
140
|
+
- **Notification service:** Push notifications for offline users
|
|
141
|
+
- **Group service:** Manages group membership and routing
|
|
142
|
+
|
|
143
|
+
### Design Decisions
|
|
144
|
+
|
|
145
|
+
| Decision | Options | Recommendation |
|
|
146
|
+
|----------|---------|----------------|
|
|
147
|
+
| **Protocol** | HTTP polling, long polling, WebSocket, SSE | WebSocket for bidirectional real-time |
|
|
148
|
+
| **Message storage** | SQL, NoSQL, wide-column | Wide-column (Cassandra/HBase) for write-heavy, time-series access |
|
|
149
|
+
| **Message ordering** | Timestamp, sequence number, hybrid | Monotonic ID per conversation (timestamp + sequence) |
|
|
150
|
+
| **Presence** | Heartbeat, connection-based | Heartbeat every 30s; mark offline after 3 missed beats |
|
|
151
|
+
| **Group message routing** | Fan-out to members, pull on read | Fan-out via message queue for groups up to ~500 members |
|
|
152
|
+
|
|
153
|
+
### Message Flow (1:1)
|
|
154
|
+
1. Sender sends message via WebSocket to connection service
|
|
155
|
+
2. Connection service publishes to message queue
|
|
156
|
+
3. Message service persists to database
|
|
157
|
+
4. If recipient is online: deliver via their WebSocket connection
|
|
158
|
+
5. If recipient is offline: send push notification, store for later delivery
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Search Autocomplete
|
|
163
|
+
|
|
164
|
+
### Requirements
|
|
165
|
+
- As user types, suggest top completions
|
|
166
|
+
- Latency under 100ms
|
|
167
|
+
- Suggestions ranked by frequency/relevance
|
|
168
|
+
|
|
169
|
+
### Key Components
|
|
170
|
+
- **Trie (prefix tree):** Data structure optimized for prefix matching
|
|
171
|
+
- **Aggregation service:** Collects search queries and computes frequencies
|
|
172
|
+
- **Cache layer:** Top-k results for popular prefixes (Redis)
|
|
173
|
+
- **Data collection service:** Logs queries for frequency analysis
|
|
174
|
+
|
|
175
|
+
### Design Decisions
|
|
176
|
+
- **Trie structure:** Each node stores a character; leaf or internal nodes store top-k completions
|
|
177
|
+
- **Pre-computation:** Compute top-k for each prefix offline (daily/hourly job), store in trie
|
|
178
|
+
- **Caching:** Cache results for popular prefixes (top 20% of prefixes serve 80% of queries)
|
|
179
|
+
- **Sharding:** Shard trie by first character or first two characters
|
|
180
|
+
- **Update frequency:** Rebuild trie hourly or daily from query logs (real-time updates are rarely needed)
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Web Crawler
|
|
185
|
+
|
|
186
|
+
### Requirements
|
|
187
|
+
- Crawl billions of web pages
|
|
188
|
+
- Respect robots.txt and rate limits
|
|
189
|
+
- Handle duplicates, broken links, and dynamic content
|
|
190
|
+
|
|
191
|
+
### Key Components
|
|
192
|
+
- **URL frontier:** Priority queue of URLs to crawl (BFS order)
|
|
193
|
+
- **Fetcher:** Downloads page content (HTTP client with timeout and retry)
|
|
194
|
+
- **DNS resolver:** Cached DNS lookups to avoid repeated resolution
|
|
195
|
+
- **Content parser:** Extracts links, text, and metadata from HTML
|
|
196
|
+
- **Deduplication:** Content hash (MD5/SHA) to detect duplicate pages
|
|
197
|
+
- **URL filter:** Removes unwanted URLs (file types, domains, robots.txt exclusions)
|
|
198
|
+
- **Storage:** Blob store for raw content, database for metadata and links
|
|
199
|
+
|
|
200
|
+
### Design Decisions
|
|
201
|
+
- **Politeness:** One connection per domain at a time; respect `Crawl-delay` in robots.txt
|
|
202
|
+
- **Priority:** Rank URLs by PageRank, freshness, or domain importance
|
|
203
|
+
- **Deduplication:** URL dedup (seen this URL?) + content dedup (seen this content at another URL?)
|
|
204
|
+
- **Trap avoidance:** Detect infinite loops (calendar pages, query parameter variations), set max URL depth
|
|
205
|
+
- **Recrawl:** Schedule recrawl based on page change frequency (detect via Last-Modified, ETag)
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Unique ID Generator
|
|
210
|
+
|
|
211
|
+
### Requirements
|
|
212
|
+
- Generate globally unique IDs at high throughput
|
|
213
|
+
- IDs should be roughly sortable by time
|
|
214
|
+
- 64-bit (fits in a long integer)
|
|
215
|
+
|
|
216
|
+
### Approaches
|
|
217
|
+
|
|
218
|
+
| Approach | Format | Pros | Cons |
|
|
219
|
+
|----------|--------|------|------|
|
|
220
|
+
| **UUID** | 128-bit random | Simple, no coordination | 128-bit (too large), not sortable |
|
|
221
|
+
| **Auto-increment (single DB)** | Sequential integer | Simple, sortable | Single point of failure, doesn't scale |
|
|
222
|
+
| **Auto-increment (multi DB)** | Even/odd or ranges per DB | Scales writes | Gaps in sequence, coordination for ranges |
|
|
223
|
+
| **Snowflake** | 64-bit: timestamp + datacenter + machine + sequence | Time-sortable, distributed, 64-bit | Clock sync dependency |
|
|
224
|
+
| **ULID** | 128-bit: timestamp + random | Sortable, simple | 128-bit |
|
|
225
|
+
|
|
226
|
+
### Snowflake ID Structure (Recommended for Most Systems)
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
| 1 bit unused | 41 bits timestamp | 5 bits datacenter | 5 bits machine | 12 bits sequence |
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
- **41-bit timestamp:** Milliseconds since custom epoch; ~69 years of IDs
|
|
233
|
+
- **5-bit datacenter ID:** Up to 32 datacenters
|
|
234
|
+
- **5-bit machine ID:** Up to 32 machines per datacenter
|
|
235
|
+
- **12-bit sequence:** Up to 4,096 IDs per millisecond per machine
|
|
236
|
+
- **Total capacity:** 4,096 x 32 x 32 = ~4 million IDs/second system-wide
|
|
237
|
+
|
|
238
|
+
### Design Decisions
|
|
239
|
+
- **Clock sync:** Use NTP; if clock goes backward, wait or reject (never generate duplicate)
|
|
240
|
+
- **Custom epoch:** Start from your launch date, not Unix epoch (maximizes timestamp range)
|
|
241
|
+
- **Machine ID assignment:** Use ZooKeeper, etcd, or config to assign unique machine IDs
|
|
242
|
+
- **Sequence overflow:** If 4,096 exhausted in one millisecond, wait for next millisecond
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Design Pattern Summary
|
|
247
|
+
|
|
248
|
+
| System | Key Pattern | Key Tradeoff |
|
|
249
|
+
|--------|------------|-------------|
|
|
250
|
+
| URL shortener | Base62 encoding + key-value store | 301 vs 302 redirect |
|
|
251
|
+
| Rate limiter | Token bucket + Redis counters | Accuracy vs memory |
|
|
252
|
+
| Notification | Per-channel queues + retry | Reliability vs latency |
|
|
253
|
+
| News feed | Hybrid fanout (push + pull) | Write amplification vs read latency |
|
|
254
|
+
| Chat | WebSocket + message queue | Connection statefulness vs scalability |
|
|
255
|
+
| Autocomplete | Trie + top-k precomputation | Freshness vs latency |
|
|
256
|
+
| Web crawler | BFS frontier + politeness | Crawl speed vs politeness |
|
|
257
|
+
| ID generator | Snowflake (time + machine + sequence) | Coordination vs simplicity |
|