System Design Review skill for Claude Code
Turn 'it scales' into numbers and ranked findings. Claude reviews a design doc the way a staff engineer would: it writes down the requirements and assumptions, runs back-of-envelope numbers for peak traffic, storage and fan-out, traces each hot path hop by hop, and walks failure modes per component. The result is a short, severity-ranked list of findings, each with the tradeoff and a concrete alternative.
- name
system-design-review - size177 lines · ≈1,900 tokens
- files2
- licenseMIT
- updated
What Claude sees before loading it
This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.
description: Reviews a proposed system design or architecture document by pinning down functional and non-functional requirements, running back-of-envelope estimates for traffic, storage, and bandwidth, tracing data flow for key use cases, and finding bottlenecks, single points of failure, consistency gaps, and missing operational concerns. Produces a severity-ranked review with tradeoffs and concrete alternatives. Use when asked to review a design doc, RFC, or architecture diagram, sanity-check scale assumptions, prepare for a design review meeting, or evaluate whether a design will hold at 10x load. Try asking
- Review this design doc for our notifications service before Thursday's meeting
- Will this architecture hold at 10x our current traffic? Here's the diagram
- Sanity-check the storage and throughput estimates in this RFC
Use it when
- A design doc, RFC, or architecture diagram needs review
- Scale or availability claims need estimates behind them
- Preparing questions for a design review meeting
- Checking what breaks first under growth
Skip it when
- You need to write the design doc itself: use design-docs-rfc
- You are modeling security threats specifically: use threat-modeling
How to check the result
Every finding cites a requirement or an estimate with units, the top risk at 10x load is named, and each blocker or major finding has a concrete alternative with its tradeoff.
The common mistake it prevents
Sizing for average traffic and ignoring fan-out or hot keys, so the design looks fine on paper and fails at the first peak.
A useful design review turns vague claims (“it scales”) into numbers, follows real requests through the design, and names the specific failure that will happen first. The output is a short list of ranked findings with alternatives, not a rewrite of the design.
Ground rules
- Review against stated requirements. If requirements are missing, write the assumed ones down and flag them as the first finding.
- Every scale claim gets an estimate with units. “High traffic” is not a number.
- Distinguish blockers from preferences. A different but workable database choice is not a finding.
- Prefer the simplest design that meets the numbers. Complexity needs a requirement that justifies it.
- Name the tradeoff the author made, even when you agree with it, so it is explicit.
Workflow
- [ ] 1. Extract requirements and constraints (write assumptions explicitly)
- [ ] 2. Back-of-envelope estimates: QPS, peak, storage, bandwidth, fan-out
- [ ] 3. Trace 2–4 critical use cases end to end
- [ ] 4. Check the data model against access patterns
- [ ] 5. Find bottlenecks at 1x and 10x
- [ ] 6. Walk failure modes component by component
- [ ] 7. Check consistency, security, operability, cost, migration
- [ ] 8. Write ranked findings with alternatives
1. Requirements
Fill this table before judging anything:
| Dimension | Question | Example answer |
|---|---|---|
| Users and actions | Who does what, how often? | 2M DAU, 20 reads + 2 writes per user/day |
| Latency | Target per operation at p95/p99 | Feed read p95 < 200 ms |
| Availability | SLO and what “down” means | 99.9% monthly on read path |
| Consistency | Which reads must see which writes? | Own posts visible immediately; others within 5 s |
| Durability | Acceptable data loss (RPO), recovery time (RTO) | RPO 1 min, RTO 30 min |
| Growth | Horizon and expected multiplier | 5x in 18 months |
| Constraints | Team size, budget, compliance, existing stack | 6 engineers, GDPR, AWS, Postgres expertise |
2. Estimates
Use round numbers and orders of magnitude. 1 day ≈ 10^5 seconds.
Writes: 2M users x 2/day = 4M/day ≈ 46/s avg → peak x5 ≈ 250/s
Reads: 2M users x 20/day = 40M/day ≈ 460/s avg → peak x5 ≈ 2,500/s
Storage: 4M posts/day x 1 KB = 4 GB/day ≈ 1.5 TB/year (+indexes, replicas: x3)
Fan-out: avg 200 followers x 250 writes/s = 50k timeline inserts/s if fan-out-on-write
The fan-out line is often where designs break. Latency, throughput, and availability rules of thumb are in references/estimation-cheatsheet.md; read it when you need reference numbers for a component.
3. Trace critical paths
For each key use case, list every hop with its expected latency and what happens if it fails:
POST /posts: client → LB (1 ms) → API (5 ms) → Postgres insert (3 ms)
→ outbox → queue → fan-out worker → Redis timelines (async)
Read feed: client → CDN miss → API → Redis timeline (1 ms) → hydrate 50 posts
from Postgres (N+1 risk!) → response
Look for: synchronous chains longer than 3–4 services, N+1 hydration, calls across regions on the hot path, work done on the request path that could be async.
4. Data model vs. access patterns
- List every query the hot paths need, with its frequency. Check each has an index or a key-based lookup; check no hot path needs a cross-shard join or full scan.
- Check the partition/shard key distributes load (no celebrity user or single tenant dominating one partition).
- Check data growth: which tables grow unbounded, what is the retention policy?
5. Bottlenecks
| Component | Check |
|---|---|
| Database | Write rate vs. single-primary capacity; connection count vs. pool limits; largest table size; hot rows (counters, locks) |
| Cache | Hit ratio assumption; behavior on cold start or flush (thundering herd); eviction policy; key cardinality |
| Queue/stream | Partition count vs. consumer parallelism; ordering requirements; consumer lag at peak |
| Stateless services | CPU per request x peak QPS; autoscaling lag vs. spike shape |
| External APIs | Their rate limits and latency at your peak |
| Network | Payload size x QPS; cross-AZ/region egress cost |
Ask “what breaks first at 10x?” and name it. That is usually the most valuable finding.
6. Failure modes
Walk each component and dependency:
| Component | Failure | Detection | Impact | Mitigation in design? |
|---|---|---|---|---|
| Postgres primary | Crash / failover (30–60 s) | Health check | Writes fail | Retries with idempotency? |
| Redis | Eviction or restart | Hit ratio alert | DB load spike x20 | Request coalescing? |
| Payment provider | Latency 10 s | p99 alert | Threads exhausted | Timeout + circuit breaker? |
| Queue consumer | Poison message | DLQ depth | Stuck partition | DLQ + skip? |
| Region | Outage | External probe | Full outage | Required by SLO? |
Also check: retries without backoff (amplification), missing timeouts, unbounded queues, cascading failure through shared dependencies, deploys and migrations as failure events.
7. Cross-cutting checklist
- Consistency: where is the source of truth? Dual writes without an outbox? Cache invalidation strategy? Read-your-writes requirements met?
- Idempotency: every retried operation has a key or natural idempotence.
- Security: authn/authz at each entry point, tenant isolation, secrets, PII flows, encryption in transit and at rest.
- Operability: metrics, traces, alerts tied to SLOs, runbooks, feature flags for rollout, backfill and replay tools.
- Cost: biggest line items at expected scale (egress, managed DB size, per-request pricing of third parties).
- Evolution: schema migration strategy, API versioning, how to roll back.
- Simplicity: could a single Postgres + a queue meet the numbers for the next 2 years?
8. Write findings
Severity levels:
- Blocker: will not meet a stated requirement or will lose/corrupt data.
- Major: likely incident or rework within the growth horizon.
- Minor: improvement with clear benefit, not urgent.
- Question: missing information needed to judge.
Output template
# Design review: <design name> (<doc link>, reviewed <date>)
## Summary
One paragraph: overall assessment, the top risk, and whether it can proceed.
## Requirements as understood
<table from step 1; mark assumptions with (assumed)>
## Estimates
<calculations from step 2>
## Findings
1. **[Blocker] Fan-out-on-write cannot sustain peak.** 250 posts/s x 200 followers =
50k Redis writes/s, with celebrity accounts at 1M followers producing 1M writes per
post. *Alternative:* hybrid fan-out (push for accounts < 10k followers, pull at read
time for large accounts). *Tradeoff:* more complex read path.
2. **[Major] Order service calls inventory and payment synchronously with no timeouts.**
...
3. **[Question] What is the RPO for the events store?** ...
## Tradeoffs the design makes (agreed)
- Eventual consistency on follower feeds (≤ 5 s) in exchange for write scalability.
## Suggested next steps
- Load test the read path at 3,000 req/s before launch.
- Write an ADR for the fan-out choice.
Gotchas
- Averages hide peaks. Size for peak (often 3–10x average) and for the spike shape.
- “We’ll add caching” without a hit ratio and invalidation story is not a plan.
- Microservices proposed for a small team often fail on operability, not scale.
- Reviews that rewrite the whole design get ignored. Limit to the top 5–8 findings.
- A design without a migration and rollback plan for existing data is incomplete.
Bundled files
Loaded only when a step in the skill needs them. Review them here before installing.
references/estimation-cheatsheet.md
# Estimation cheat sheet
Read this when you need reference numbers for back-of-envelope estimates. All figures
are order-of-magnitude guides for typical cloud hardware in 2025–2026. Replace them with
measured numbers from the actual system whenever available, and say which you used.
## Time conversions
| Quantity | Value |
|---|---|
| Seconds per day | 86,400 ≈ 10^5 |
| Seconds per month | ~2.6 x 10^6 |
| 1M requests/day | ~12 req/s average |
| 100M requests/day | ~1,160 req/s average |
| Peak-to-average ratio | 2–3x for business apps, 5–10x for consumer/event-driven traffic |
## Latency (approximate)
| Operation | Typical |
|---|---|
| Main memory reference | ~100 ns |
| Read 1 MB sequentially from memory | tens of µs |
| NVMe SSD random read | ~0.1 ms |
| Network round trip, same availability zone | 0.1–0.5 ms |
| Round trip, cross-AZ same region | 0.5–2 ms |
| Round trip, US east ↔ US west | ~60–80 ms |
| Round trip, US ↔ Europe | ~70–110 ms |
| Round trip, US ↔ Asia-Pacific | ~150–250 ms |
| Redis GET (same AZ, incl. network) | 0.2–1 ms |
| Indexed Postgres point lookup (incl. network) | 0.5–3 ms |
| New TLS connection setup | 1–2 extra round trips |
| HDD seek | 5–10 ms |
Implication: a request that makes 5 sequential cross-region calls cannot meet a 200 ms
p95 budget.
## Throughput (single node, very rough)
| Component | Ballpark | Notes |
|---|---|---|
| Stateless API instance (simple JSON) | 1k–10k req/s | Depends heavily on runtime and work per request |
| Postgres simple indexed reads | 10k–50k/s | Per primary or replica; connection count matters |
| Postgres writes | 1k–20k TPS | Row size, indexes, fsync, and replication mode dominate |
| Redis (single instance) | ~100k+ simple ops/s | Single-threaded command execution; big values and Lua cut this |
| Kafka partition | ~10 MB/s comfortable | Scale with partitions; consumer parallelism ≤ partition count |
| SQS standard queue | Very high, effectively unlimited | FIFO queues have per-group ordering limits |
| Object storage (S3) | Thousands of req/s per prefix | Scale by prefix; per-request pricing matters |
## Storage
- Row size estimate: sum of column sizes + ~25–30 bytes Postgres row overhead; indexes
commonly add 50–150% of table size.
- Plan for: replicas (x2–3), backups and PITR WAL retention, and growth horizon.
- Example: 10M rows/day x 500 B = 5 GB/day raw ≈ 1.8 TB/year; with indexes and two
replicas ≈ 8–10 TB provisioned across nodes.
## Bandwidth
- Egress = response size x QPS. 2,500 req/s x 50 KB = 125 MB/s ≈ 1 Gbit/s.
- Cross-AZ and internet egress are billed; at sustained rates they can exceed compute cost.
## Availability math
| SLO | Downtime per month | Per year |
|---|---|---|
| 99% | ~7.3 h | ~3.65 days |
| 99.9% | ~43.8 min | ~8.8 h |
| 99.95% | ~21.9 min | ~4.4 h |
| 99.99% | ~4.4 min | ~52.6 min |
- Serial dependencies multiply: three 99.9% services in series ≈ 99.7%.
- Redundant parallel components: unavailability multiplies (two independent 99% nodes ≈
99.99%), but only if failures are truly independent and failover works.
## Little's law
Concurrency = throughput x latency. 1,000 req/s at 200 ms average = 200 requests in
flight. Use it to size thread pools, DB connection pools, and worker counts, and to see
when a downstream slowdown will exhaust them (latency doubles → in-flight doubles).
## Quick sanity checks
- Can it fit on one machine? Modern instances offer hundreds of GB of RAM and tens of
TB of NVMe. Many "big data" problems are single-node problems.
- Does the working set fit in cache memory? If not, the cache hit ratio assumption is
wrong.
- Is any single key, row, or partition receiving more than ~1–5% of total traffic? That
is a hotspot regardless of total capacity.
About this skill
Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.