System Design
Define the high-level structure of a system: its components, their responsibilities, how they communicate, and where they run.
Context
System design translates requirements and domain knowledge into a technical blueprint. A well-designed architecture absorbs change gracefully -- poor design decisions compound over time and become exponentially expensive to reverse. Invest here before writing code. Every subsequent skill in the architecture and implementation phases depends on the decisions made here.
In spec-driven work, system design often starts from a reviewed spec package. In agile and brownfield work, it may start from a reviewed requirements document with open questions still visible. Do not silently "fix" requirement ambiguity inside the architecture. Preserve unresolved scope, compatibility, and quality-bound questions as design constraints or architectural open questions.
Inputs
- requirements-doc -- Minimum required input. Functional and non-functional requirements with priority rankings, scope boundaries, and unresolved questions. Pay special attention to quality attributes (latency, throughput, availability, consistency) and brownfield coexistence constraints.
- spec-doc -- Optional amplifying input when spec-driven or waterfall work produces a detailed specification.
- domain-model -- Optional amplifying input when the problem has enough domain complexity that entity boundaries or ubiquitous language should shape component boundaries.
Process
Step 1: Identify Architectural Drivers
Extract the top 5-7 quality attributes that will shape the architecture. Rank them by importance. Common drivers include:
- Performance (latency, throughput)
- Scalability (horizontal, vertical)
- Availability (uptime targets, failover)
- Security (data sensitivity, compliance)
- Maintainability (team size, release cadence)
- Cost (infrastructure budget, operational overhead)
If a driver is implied but not yet quantified, keep it as an architectural question or assumption. Do not convert vague inputs into false precision.
Step 2: Choose Architectural Style
Select the primary style based on drivers. Map each driver to the style that best supports it:
- Monolith -- Small team, simple deployment, strong consistency needs
- Microservices -- Independent scaling, team autonomy, polyglot requirements
- Serverless -- Event-driven workloads, unpredictable traffic, minimal ops budget
- Event-driven -- Loose coupling, eventual consistency acceptable, complex workflows
- Hybrid -- Most real systems combine styles; document where each applies and why
Step 3: Define Component Boundaries
Use the C4 model to work top-down:
- Context level -- Draw the system boundary. Identify all external actors (users, systems, services). Document what crosses the boundary.
- Container level -- Break the system into deployable units (web app, API, database, message queue). Assign responsibilities to each.
- Component level -- Within each container, identify major structural components (modules, services, repositories). Define interfaces between them.
- Code level -- Defer to implementation phase. Only sketch here if a component has unusual complexity.
For brownfield work, explicitly identify:
- legacy components that must remain in service
- seams where coexistence, routing, or facade patterns are needed
- boundaries that are intentionally deferred because migration rules are still unresolved
Step 4: Design Communication Patterns
For each component-to-component interaction, decide:
- Synchronous (REST, gRPC) vs asynchronous (message queue, event bus)
- Request/response vs publish/subscribe vs command/query
- Data format and contract (JSON, Protobuf, Avro)
- Failure handling (retries, circuit breakers, dead-letter queues)
Step 5: Document Deployment Topology
Define where each container runs:
- Cloud provider and region strategy
- Container orchestration (Kubernetes, ECS) or serverless platform
- Network boundaries (VPC, subnets, load balancers)
- Data residency and compliance constraints
Keep topology at the level needed for architectural reasoning. Detailed rollout plans, traffic percentages, and migration sequencing belong in later delivery planning unless they are true architectural constraints.
Step 6: Create Architecture Decision Records
For every significant decision, write an ADR:
- Title -- Short noun phrase (e.g., "Use PostgreSQL for primary data store")
- Status -- Proposed, Accepted, Deprecated, Superseded
- Context -- What forces are at play
- Decision -- What was decided
- Consequences -- What becomes easier, what becomes harder
Step 7: Conduct Trade-Off Analysis
For each major decision, document:
- What you gain (the primary benefit)
- What you sacrifice (the cost or risk)
- What would trigger reconsidering this decision (the trigger)
Outputs
- architecture-doc -- Written document covering architectural style, component boundaries, communication patterns, deployment topology, and all ADRs. Must be understandable by any developer joining the team.
- component-diagram -- C4 diagrams at context, container, and component levels. Use a tool that supports version control (Structurizr DSL, Mermaid, PlantUML).
Quality Gate
Anti-Patterns
- Resume-Driven Architecture -- Choosing technologies because they look impressive rather than because they solve the problem. Always start from drivers, not from tools.
- Big Design Up Front -- Trying to nail every detail before writing code. Design to the level of certainty you have; mark unknowns as spikes for validation during implementation.
- Distributed Monolith -- Splitting into microservices without achieving independent deployability. If services must deploy together, they are not separate services.
- Ignoring the "-ilities" -- Focusing only on functional requirements. Non-functional requirements (scalability, observability, security) are architectural concerns -- they rarely emerge from good intentions alone.
- Architecture Astronautics -- Over-abstracting and over-generalizing for hypothetical future needs. Design for today's known requirements with extension points for likely changes.
- Closing open questions by accident -- Turning unresolved compatibility, synchronization, or rollout questions into assumed architecture facts without labeling them as assumptions or follow-up decisions.
Related Skills
- spec-writing -- Provides the spec-doc input
- domain-modeling -- Provides bounded contexts that inform component boundaries
- api-design -- Designs the interfaces between components defined here
- data-modeling -- Translates the domain model into storage schemas within this architecture
- security-design -- Layers security controls onto the architecture
- tech-selection -- Evaluates concrete technologies for the components defined here
- task-breakdown -- Decomposes the architecture into implementable tasks
1---2name: system-design3description: Use when reviewed requirements or specifications are ready and the team must decide high-level architecture, component boundaries, integration seams, or brownfield coexistence strategy before API design, technology selection, or task planning.4---56# System Design78> Define the high-level structure of a system: its components, their responsibilities, how they communicate, and where they run.910## Context1112System design translates requirements and domain knowledge into a technical blueprint. A well-designed architecture absorbs change gracefully -- poor design decisions compound over time and become exponentially expensive to reverse. Invest here before writing code. Every subsequent skill in the architecture and implementation phases depends on the decisions made here.1314In spec-driven work, system design often starts from a reviewed spec package. In agile and brownfield work, it may start from a reviewed requirements document with open questions still visible. Do not silently "fix" requirement ambiguity inside the architecture. Preserve unresolved scope, compatibility, and quality-bound questions as design constraints or architectural open questions.1516## Inputs1718- **requirements-doc** -- Minimum required input. Functional and non-functional requirements with priority rankings, scope boundaries, and unresolved questions. Pay special attention to quality attributes (latency, throughput, availability, consistency) and brownfield coexistence constraints.19- **spec-doc** -- Optional amplifying input when spec-driven or waterfall work produces a detailed specification.20- **domain-model** -- Optional amplifying input when the problem has enough domain complexity that entity boundaries or ubiquitous language should shape component boundaries.2122## Process2324### Step 1: Identify Architectural Drivers2526Extract the top 5-7 quality attributes that will shape the architecture. Rank them by importance. Common drivers include:27- Performance (latency, throughput)28- Scalability (horizontal, vertical)29- Availability (uptime targets, failover)30- Security (data sensitivity, compliance)31- Maintainability (team size, release cadence)32- Cost (infrastructure budget, operational overhead)3334If a driver is implied but not yet quantified, keep it as an architectural question or assumption. Do not convert vague inputs into false precision.3536### Step 2: Choose Architectural Style3738Select the primary style based on drivers. Map each driver to the style that best supports it:39- **Monolith** -- Small team, simple deployment, strong consistency needs40- **Microservices** -- Independent scaling, team autonomy, polyglot requirements41- **Serverless** -- Event-driven workloads, unpredictable traffic, minimal ops budget42- **Event-driven** -- Loose coupling, eventual consistency acceptable, complex workflows43- **Hybrid** -- Most real systems combine styles; document where each applies and why4445### Step 3: Define Component Boundaries4647Use the C4 model to work top-down:481. **Context level** -- Draw the system boundary. Identify all external actors (users, systems, services). Document what crosses the boundary.492. **Container level** -- Break the system into deployable units (web app, API, database, message queue). Assign responsibilities to each.503. **Component level** -- Within each container, identify major structural components (modules, services, repositories). Define interfaces between them.514. **Code level** -- Defer to implementation phase. Only sketch here if a component has unusual complexity.5253For brownfield work, explicitly identify:54- legacy components that must remain in service55- seams where coexistence, routing, or facade patterns are needed56- boundaries that are intentionally deferred because migration rules are still unresolved5758### Step 4: Design Communication Patterns5960For each component-to-component interaction, decide:61- Synchronous (REST, gRPC) vs asynchronous (message queue, event bus)62- Request/response vs publish/subscribe vs command/query63- Data format and contract (JSON, Protobuf, Avro)64- Failure handling (retries, circuit breakers, dead-letter queues)6566### Step 5: Document Deployment Topology6768Define where each container runs:69- Cloud provider and region strategy70- Container orchestration (Kubernetes, ECS) or serverless platform71- Network boundaries (VPC, subnets, load balancers)72- Data residency and compliance constraints7374Keep topology at the level needed for architectural reasoning. Detailed rollout plans, traffic percentages, and migration sequencing belong in later delivery planning unless they are true architectural constraints.7576### Step 6: Create Architecture Decision Records7778For every significant decision, write an ADR:79- **Title** -- Short noun phrase (e.g., "Use PostgreSQL for primary data store")80- **Status** -- Proposed, Accepted, Deprecated, Superseded81- **Context** -- What forces are at play82- **Decision** -- What was decided83- **Consequences** -- What becomes easier, what becomes harder8485### Step 7: Conduct Trade-Off Analysis8687For each major decision, document:88- What you gain (the primary benefit)89- What you sacrifice (the cost or risk)90- What would trigger reconsidering this decision (the trigger)9192## Outputs9394- **architecture-doc** -- Written document covering architectural style, component boundaries, communication patterns, deployment topology, and all ADRs. Must be understandable by any developer joining the team.95- **component-diagram** -- C4 diagrams at context, container, and component levels. Use a tool that supports version control (Structurizr DSL, Mermaid, PlantUML).9697## Quality Gate9899- [ ] Architecture review completed with at least two reviewers100- [ ] All significant decisions captured as ADRs101- [ ] Component boundaries align with domain bounded contexts102- [ ] Quality attribute trade-offs explicitly documented103- [ ] Deployment topology accounts for failure modes104- [ ] C4 diagrams at context, container, and component levels exist105- [ ] No circular dependencies between components106107## Anti-Patterns1081091. **Resume-Driven Architecture** -- Choosing technologies because they look impressive rather than because they solve the problem. Always start from drivers, not from tools.1102. **Big Design Up Front** -- Trying to nail every detail before writing code. Design to the level of certainty you have; mark unknowns as spikes for validation during implementation.1113. **Distributed Monolith** -- Splitting into microservices without achieving independent deployability. If services must deploy together, they are not separate services.1124. **Ignoring the "-ilities"** -- Focusing only on functional requirements. Non-functional requirements (scalability, observability, security) are architectural concerns -- they rarely emerge from good intentions alone.1135. **Architecture Astronautics** -- Over-abstracting and over-generalizing for hypothetical future needs. Design for today's known requirements with extension points for likely changes.1146. **Closing open questions by accident** -- Turning unresolved compatibility, synchronization, or rollout questions into assumed architecture facts without labeling them as assumptions or follow-up decisions.115116## Related Skills117118- [spec-writing](../../01-specification/spec-writing/SKILL.md) -- Provides the spec-doc input119- [domain-modeling](../../01-specification/domain-modeling/SKILL.md) -- Provides bounded contexts that inform component boundaries120- [api-design](../api-design/SKILL.md) -- Designs the interfaces between components defined here121- [data-modeling](../data-modeling/SKILL.md) -- Translates the domain model into storage schemas within this architecture122- [security-design](../security-design/SKILL.md) -- Layers security controls onto the architecture123- [tech-selection](../tech-selection/SKILL.md) -- Evaluates concrete technologies for the components defined here124- [task-breakdown](../../03-planning/task-breakdown/SKILL.md) -- Decomposes the architecture into implementable tasks