$npx -y skills add proyecto26/system-design-skills --skill scaling-evolutionThis skill should be used when the user asks "how does this scale", "scale to millions", "scaling roadmap", "where is the bottleneck", "what breaks first", "10x growth", "vertical vs horizontal scaling", "scale from zero", or "what's the next scale curve". It gives the order-of-m
| 1 | # Scaling Evolution |
| 2 | |
| 3 | Grow a design one bottleneck at a time. A system that serves 1k users and one |
| 4 | that serves 10M users are different architectures, but you do not jump between |
| 5 | them — you walk a path where each step removes the *current* ceiling and exposes |
| 6 | the next. Getting this wrong means either over-building day one (paying multi- |
| 7 | region complexity for 1k users) or freezing when load doubles because the design |
| 8 | was a memorized end-state, not a sequence of justified moves (GUIDE #7). |
| 9 | |
| 10 | ## When to reach for this |
| 11 | A load increase is on the table ("what if traffic 10×?", "scale to millions"), |
| 12 | the user asks where the bottleneck is or what breaks first, or a single-box |
| 13 | design has outgrown one machine. Reach here to sequence the next two or three |
| 14 | moves — never the whole roadmap at once. |
| 15 | |
| 16 | ## When NOT to |
| 17 | Do not pre-build steps the numbers do not yet demand (YAGNI). Sharding, |
| 18 | multi-region, and a message queue are *late* moves; proposing them for a system |
| 19 | that fits on two boxes is the over-indexing this skill defends against. If the |
| 20 | current load fits comfortably on a vertically-scaled box with a replica, stop — |
| 21 | that is the cheapest design that meets the constraint, and it wins. Naming the |
| 22 | next five tiers when only one is needed is a red flag, not foresight. |
| 23 | |
| 24 | ## Clarify first |
| 25 | The path is driven entirely by numbers and constraints, so pin these down before |
| 26 | moving (most come from `requirements-scoping` and `back-of-the-envelope`): |
| 27 | - **Current and target scale** — today's QPS/data and the multiple you must hit |
| 28 | (2×? 100×?). The multiple decides how many steps you take now. |
| 29 | - **Read:write ratio** — read-heavy systems scale with replicas + cache; write- |
| 30 | heavy systems hit the master/storage ceiling and need sharding far sooner. |
| 31 | - **Where it hurts now** — is the *symptom* compute (CPU saturated), storage |
| 32 | (DB/disk saturated), or network (bandwidth/connections)? Diagnose before adding. |
| 33 | - **Consistency and staleness budget** — replicas and multi-region trade freshness |
| 34 | for scale; if reads must be current, that constrains the path (→ `consistency-coordination`). |
| 35 | - **State** — is anything pinned to a server (sessions, local files)? Stateful |
| 36 | tiers block horizontal scaling. |
| 37 | |
| 38 | ## The method: walk the bottleneck ladder |
| 39 | Each rung removes one ceiling. Apply the **next** rung the numbers justify, not |
| 40 | the whole ladder. Full triggers and worked thresholds are in |
| 41 | `references/scaling-ladder.md`. |
| 42 | |
| 43 | 1. **Single server.** Web, app, DB, cache on one box. Correct for low traffic and |
| 44 | early validation. *Breaks when* one machine can't hold the load or the data. |
| 45 | 2. **Split the tiers.** Move the database (and later cache) onto its own host so |
| 46 | web and data scale independently. *Breaks when* the single web box or single DB |
| 47 | saturates, or either becomes a single point of failure. |
| 48 | 3. **Vertical scale + replicate for reads.** First scale *up* (bigger box — simple, |
| 49 | no app changes) until the hard limit or cost knee. Add read replicas to spread |
| 50 | reads off the primary (→ `data-storage` owns replication). *Breaks when* writes |
| 51 | saturate the primary, or replica lag breaks freshness. |
| 52 | 4. **Add a cache.** Put hot reads in front of the DB once a number shows reads |
| 53 | dominate (→ `caching`). Highest-leverage move for read-heavy systems. *Breaks |
| 54 | when* writes are the bottleneck, or the working set no longer fits. |
| 55 | 5. **Push static/edge to a CDN.** Offload images/JS/CSS/video to edge servers |
| 56 | close to users (→ `content-delivery`). *Breaks when* the bottleneck is dynamic |
| 57 | requests, not static assets. |
| 58 | 6. **Make the web tier stateless + load-balance.** Move session/state to a shared |
| 59 | store so any request hits any server; put a load balancer in front and |
| 60 | autoscale the fleet (→ `load-balancing`). This is the unlock for cheap |
| 61 | horizontal scale. *Breaks when* the data tier (now the bottleneck) can't keep up. |
| 62 | 7. **Decouple with async.** Move slow/bursty work (uploads, encoding, fan-out) |
| 63 | behind a queue so producers and consumers scale independently and spikes are |
| 64 | absorbed (→ `messaging-streaming`). *Breaks when* even the sync path or storage |
| 65 | is the limit. |
| 66 | 8. **Multi-DC / multi-region.** Geo-route users to the nearest healthy data center |
| 67 | for latency and disaster survival; replicate across regions. *Breaks when* |
| 68 | cross-region data sync, conflict resolution, or a single dataset too big f |