System Design Review skill for Codex
Find what breaks first, with the math to prove it. Codex reviews architecture proposals against stated requirements instead of an idealised design. It does the capacity arithmetic in writing, walks each critical dependency through slow, down and garbage responses, checks data ownership and dual writes, and flags over-engineering as well as gaps. Findings come ranked, each with a failure scenario or number and an actionable fix.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- system-design-review Installs to ~/.agents/skills/system-design-review/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install system-design-review The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project system-design-review Installs to .agents/skills/system-design-review/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/system-design-review.zipunzip -o system-design-review.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) system-design-review PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $system-design-review, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Reviews a proposed or existing system design for scale, failure modes, data consistency, security, operability and cost - checks load math, single points of failure, timeouts and retries, data ownership, migration path and blast radius - and returns ranked, evidence-backed findings with concrete fixes. Use when asked to review an architecture doc, design proposal, RFC, diagram or service layout, before a launch or major scale-up, or for a pre-mortem on "what breaks first".
Use it when
- A design doc, RFC or architecture diagram needs a critical read before build
- A system is about to face a launch, migration or large traffic increase
- You want an outside view on failure modes and single points of failure
- Costs are growing and you suspect the design, not the usage
Use something else when
- You are reviewing an API contract rather than a whole system: use api-design-review
- You need detailed load estimates and scaling plans as the main output: use capacity-planning
- The review is a security threat model: use threat-modeling
How to check the result
Every critical and high finding carries a reproducible scenario or calculation, and every stated requirement appears in the report as met, not met or unknown with evidence.
The mistake it prevents
Reviewing the diagram instead of the deployed system, and missing that real timeouts, pool sizes and replica counts differ from what the document claims.
A useful review finds the two or three things that will actually hurt (the outage, the data loss, the bill) and backs each with a number or a failure sequence. It checks the design against stated requirements, not against an ideal architecture, and leaves the authors with fixes they can schedule.
Gather inputs first
Do not review before you know what “good” means for this system.
- Read the design doc, diagrams and any linked ADRs. In a repo, read
AGENTS.md, then skim service entry points, infra code (terraform/,k8s/,docker-compose.yml) and config to see what is really deployed, not just what the doc claims. - Extract or ask for the requirements. If missing, state your assumptions explicitly:
| Requirement | Ask for | Example |
|---|---|---|
| Load | Peak requests/s, read:write ratio, growth over 12-24 months | 1.2k rps peak, 20:1 reads, 3x in a year |
| Data | Volume now and in 2 years, record size, retention | 400 GB, 2 KB rows, keep 7 years |
| Latency | p50/p99 target per critical path | Checkout p99 < 800 ms |
| Availability | SLO and what counts as down | 99.9% monthly on checkout API |
| Durability / consistency | Which data must never be lost or double-applied | Payments exactly-once effect |
| Constraints | Team size, budget, compliance, existing platform | 4 engineers, PCI scope, AWS only |
- Draw (or reconstruct) the request path for the top two user journeys, hop by hop. Most findings come from walking these paths with a failure in mind.
Review passes
Run each pass over the whole design. Write findings as you go.
| # | Pass | Core questions |
|---|---|---|
| 1 | Requirements fit | Does the design meet each stated number? Is anything over-built for the load? |
| 2 | Capacity math | Rough throughput, storage and connection counts per component at peak and at 3x |
| 3 | Failure modes | For each dependency: what happens when it is slow, down, or returns garbage? |
| 4 | Data | Who owns each dataset? Consistency model? What happens on partial writes? |
| 5 | Coupling | Synchronous call chains, shared databases, deploy-together services |
| 6 | Security | Trust boundaries, authn/authz per entry point, secrets, PII flow, tenant isolation |
| 7 | Operability | Observability, deploy and rollback, migrations, on-call burden, runbooks |
| 8 | Cost | Dominant cost drivers and how they scale with load |
| 9 | Evolution | Migration path from today, reversibility, what the next 10x needs |
For per-pass checklists with specific probes, read references/review-checklist.md when a pass needs depth (for example, a design with queues, multi-region, or regulated data).
Back-of-envelope checks
Do the arithmetic in the review; it is the fastest way to find real problems.
Peak writes: 1.2k rps x 5% writes = 60 writes/s -> one Postgres primary is fine (headroom > 10x)
Fan-out: each order emits 4 events x 3 consumers = 720 msg/s at peak -> trivial for SQS/Kafka
Sync chain: gateway -> orders -> inventory -> pricing -> tax, each p99 150 ms
-> worst case approaches 600 ms before retries and the app's own work; budget is gone
Fan-out: one request calls 10 shards in parallel -> 1 - 0.99^10 ~ 10% of requests
wait on at least one shard's p99; the page's p90 becomes the shards' p99
Availability: 4 serial dependencies at 99.9% each -> ~99.6% best case, below a 99.9% SLO
Connections: 40 pods x pool 20 = 800 connections vs SHOW max_connections = 1000
-> fine today, breaks when autoscaling reaches 50 pods; add a pooler (PgBouncer/RDS Proxy)
Storage: 2 KB x 5M rows/day x 365 x 7 years ~ 25 TB -> plan partitioning and archival now
Rules of thumb worth checking against:
- A serial chain’s availability is the product of its parts. Every synchronous hop added to a critical path lowers the ceiling.
- Retries multiply load: 3 layers each retrying 3 times turn one failure into up to 27 calls.
- A queue absorbs bursts, not sustained overload; check consumer throughput exceeds the producer’s sustained rate with margin.
- Caches hide load until they empty. Ask what the origin sees on a cold start or a cache flush.
Failure walk
For each critical journey, fill a table like this. Missing cells are findings.
| Dependency | Timeout | Retry policy | When it is down | When it is slow | Data risk |
|---|---|---|---|---|---|
| Payments API | 3 s | 2 retries, idempotency key | Order held as pending, retried by job | Threads pile up: needs bulkhead | None (idempotent) |
| Inventory svc | none set | client default | Checkout fails | Checkout hangs: finding | Oversell if reservation not atomic |
Severity and findings
| Severity | Meaning |
|---|---|
| critical | Data loss, security breach, or the design cannot meet a stated hard requirement |
| high | Likely outage or SLO miss under expected load or a common failure |
| medium | Operational pain, cost growth, or risk under plausible but less common conditions |
| low | Improvement, simplification, or clarity |
| question | Information missing to judge |
Each finding: what, where, a failure scenario or number, the fix, and the cost of the fix.
**high - Inventory call has no timeout (checkout path, step 3).** When inventory slows
to 10 s (seen during its nightly reindex), checkout threads block and the 200-thread pool
exhausts in ~4 s at peak, taking down all checkout traffic. Fix: 800 ms timeout, circuit
breaker, and a separate pool for inventory calls. Effort: ~1 day.
Also call out over-engineering: a Kafka cluster for 50 msg/s, microservices for a four-person team, multi-region without an SLO that needs it. Unneeded complexity is a finding with an operational cost.
Workflow
- [ ] 1. Collect requirements; write down assumptions where missing
- [ ] 2. Reconstruct the request paths for the top journeys
- [ ] 3. Run the nine passes; do the capacity arithmetic in writing
- [ ] 4. Fill the failure walk table for each critical dependency
- [ ] 5. Rank findings; merge duplicates; drop anything without a scenario or number
- [ ] 6. Identify what you could not assess and what evidence would settle it
- [ ] 7. Deliver the report (template below)
Gotchas
- Reviewing the diagram instead of the system. Check deployed config: timeouts, pool sizes, replica counts and autoscaling limits often differ from the doc.
- “We will use Kafka so it scales” is not a design. Ask for partition key, ordering needs, consumer group sizing and replay behaviour.
- Exactly-once delivery claims: look for idempotent consumers and dedup keys, not broker settings alone ($event-driven-architecture, $outbox-pattern).
- Multi-tenant designs: the noisy neighbour and the cross-tenant data leak are the two findings to look for first.
- Cost is a design property. A per-request Lambda plus NAT gateway egress can dominate the bill at scale; estimate it.
- Do not demand a rewrite. Prefer the smallest change that removes the risk, and give a path for the larger change if one is truly needed.
Verification
- Every critical and high finding has a scenario or a calculation a reader can check.
- Every stated requirement maps to a pass/fail/unknown line in the report.
- Re-read the findings as the design’s author: is each fix actionable without a meeting?
Report template
# Design review: <system> (<doc link>, <date>)
**Verdict:** ready | ready with fixes | needs another iteration
**Top risks:** 1) <one line> 2) <one line> 3) <one line>
## Requirements check
| Requirement | Target | Design meets? | Evidence |
|---|---|---|---|
## Assumptions made
## Findings (ranked)
### critical / high / medium / low / questions
## Capacity and cost notes
## What I could not assess
## Suggested next steps (ordered, with effort) What the zip contains
Codex reads bundled files only when a step points to them. Every one is shown here, so you can review it before installing.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "System Design Review"
short_description: "Find what breaks first, with the math to prove it"
default_prompt: "$system-design-review Review this design doc for the new notifications service before we build it" references/review-checklist.md
# System design review: probes per pass
Use the probes for the passes that matter to the design under review. Each "no" or
"unknown" is a candidate finding; keep it only if you can attach a scenario or number.
## 1. Requirements fit
- Is every non-functional requirement written as a number (rps, p99, RPO/RTO, SLO)?
- Is any component sized for 100x the stated load with no growth reason?
- Are read and write paths treated separately where their ratios differ by 10x or more?
## 2. Capacity
- Peak vs average: is the peak factor stated (often 3-10x for consumer traffic)?
- Database: writes/s on the primary, largest table growth, index count on hot tables.
- Connections: pods x pool size vs database connection limit, at max autoscale.
- Queues: sustained producer rate vs consumer throughput; max backlog drain time.
- Hot keys or hot partitions: one tenant, one product, one celebrity user.
- Payload sizes: large messages through brokers or gateways with size limits.
## 3. Failure modes
- Every network call has an explicit timeout below the caller's own deadline.
- Retries use backoff with jitter, a retry budget, and only on idempotent operations.
- Circuit breakers or load shedding on dependencies that can slow down.
- Bulkheads: one slow dependency cannot exhaust a shared thread or connection pool.
- Single points of failure: one NAT gateway, one AZ, one Redis primary, one cron host.
- Dependency on a third party in the critical path: what is the degraded mode?
- Thundering herd after recovery: cache stampede, synchronized retries, reconnect storms.
- Poison messages: dead-letter queue, alerting, and a replay procedure.
## 4. Data
- Each dataset has exactly one owning service that writes it.
- Consistency model stated per flow: strong, read-your-writes, eventual (with bound).
- Dual writes (DB + broker, DB + cache, DB + search) are replaced by outbox or CDC.
- Idempotency keys on externally retried writes (payments, orders, webhooks).
- Backups exist, restores are tested, RPO/RTO stated and achievable.
- Schema migrations: expand/contract, online, reversible.
- Deletion and retention: GDPR erasure path through every copy, including events and logs.
## 5. Coupling
- Length of the longest synchronous chain on a user-facing path.
- Shared database between services (who can break whom with a migration?).
- Services that must deploy together are one service in practice.
- Chatty interactions: N calls per request where one batch call would do.
## 6. Security
- Trust boundaries drawn; every entry point authenticated and authorized.
- Service-to-service authentication (mTLS, signed tokens), not network location alone.
- Tenant isolation enforced in the data layer, not only in the UI.
- Secrets in a manager with rotation; none in images, env files or logs.
- PII and payment data flows mapped; encryption in transit and at rest.
- Abuse cases: rate limits, enumeration, expensive queries reachable anonymously.
## 7. Operability
- Golden signals (latency, traffic, errors, saturation) per service; SLO-based alerts.
- Distributed tracing across async boundaries (propagated context in messages).
- Deploys are gradual (canary or blue-green) with automated rollback triggers.
- Feature flags or kill switches for risky paths.
- Runbooks for the top three expected incidents.
- Configuration per environment is explicit; no hand-edited production state.
## 8. Cost
- Dominant cost line identified (compute, storage, egress, managed service fees).
- Cost per unit of business value (per order, per active user) estimated.
- Cross-AZ and cross-region traffic and NAT gateway charges counted.
- Log and metric volume (high-cardinality labels) estimated.
- Autoscaling has a max; a bug or attack cannot scale spend without bound.
## 9. Evolution
- A migration path from the current system exists and each step is shippable.
- Reversibility: which steps are one-way doors? Are they late in the plan?
- What has to change at the next 10x, and is that change cheap to make later?
- Decisions that need ADRs are identified.
About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.