Designs software system architecture and makes high-level technical decisions. Use when planning system design, evaluating technologies, defining scalability strategies, deciding between monolith and microservices, designing data flows, or documenting architecture decisions. Covers design patterns, system integration, and technical planning.
Expert guidance for designing scalable, maintainable, and robust software architectures.
# ADR-001: [Decision Title]
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXX]
## Context
What is the issue we're addressing? What forces are at play?
## Decision
What is the change we're proposing or have agreed to implement?
## Consequences
What becomes easier or harder because of this change?
### Positive
- Benefit 1
- Benefit 2
### Negative
- Tradeoff 1
- Tradeoff 2
### Neutral
- Observation 1
## Alternatives Considered
Brief description of other options and why they weren't chosen.
| Aspect | Monolith | Microservices |
|---|---|---|
| Best for | Small teams, MVPs, simple domains | Large teams, complex domains |
| Deployment | Single unit | Independent services |
| Scaling | Vertical, entire app | Horizontal, per service |
| Complexity | Lower operational | Higher operational |
| Data | Single database | Database per service |
| Team structure | Any size | Requires larger teams |
src/
├── modules/
│ ├── users/
│ │ ├── api/ # HTTP handlers
│ │ ├── domain/ # Business logic
│ │ ├── infrastructure/# Database, external services
│ │ └── index.ts # Public API
│ ├── orders/
│ │ ├── api/
│ │ ├── domain/
│ │ ├── infrastructure/
│ │ └── index.ts
│ └── payments/
│ └── ...
├── shared/ # Cross-module utilities
└── app.ts
Benefits:
┌─────────────────────────────────────┐
│ Presentation Layer │ UI, API Controllers
├─────────────────────────────────────┤
│ Application Layer │ Use Cases, Orchestration
├─────────────────────────────────────┤
│ Domain Layer │ Business Logic, Entities
├─────────────────────────────────────┤
│ Infrastructure Layer │ Database, External APIs
└─────────────────────────────────────┘
Dependency Rule: Upper layers depend on lower layers, never reverse.
┌─────────────────────────────────────────────┐
│ Frameworks & Drivers │
│ ┌─────────────────────────────────────┐ │
│ │ Interface Adapters │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ Application Layer │ │ │
│ │ │ ┌─────────────────────┐ │ │ │
│ │ │ │ Domain Layer │ │ │ │
│ │ │ │ (Entities) │ │ │ │
│ │ │ └─────────────────────┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Dependency Rule: Dependencies point inward only.
┌─────────┐ ┌─────────────┐ ┌──────────────┐
│ Clients │────▶│ API Gateway │────▶│ Service A │
└─────────┘ │ │ ├──────────────┤
│ - Auth │────▶│ Service B │
│ - Rate Limit│ ├──────────────┤
│ - Routing │────▶│ Service C │
└─────────────┘ └──────────────┘
Responsibilities:
┌───────────┐ publish ┌───────────────┐ subscribe ┌───────────┐
│ Service A │─────────────▶│ Message Broker │◀───────────────│ Service B │
└───────────┘ │ (Kafka/RMQ) │ └───────────┘
└───────────────┘
│
▼ subscribe
┌───────────┐
│ Service C │
└───────────┘
Event Types:
┌─────────────────────────────────────────────────────┐
│ Application │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Command Side │ │ Query Side │ │
│ │ │ │ │ │
│ │ - Create Order │ │ - Get Order │ │
│ │ - Update Order │ │ - List Orders │ │
│ │ - Cancel Order │ │ - Search Orders │ │
│ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ Write Database │────▶│ Read Database │ │
│ │ (Normalized) │ sync│ (Denormalized) │ │
│ └────────────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────┘
Use CQRS when:
┌───────────────┐
│ Load Balancer │
└───────┬───────┘
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Server 1 │ │ Server 2 │ │ Server 3 │
└──────────┘ └──────────┘ └──────────┘
Requirements for horizontal scaling:
Read Replicas:
┌────────────┐ ┌────────────────┐
│ Primary │─────▶│ Read Replica 1 │
│ (writes) │ ├────────────────┤
└────────────┘─────▶│ Read Replica 2 │
├────────────────┤
────▶│ Read Replica N │
└────────────────┘
Sharding:
┌────────────────────────────────────┐
│ Shard Router │
└──────────────┬─────────────────────┘
┌───────┴───────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Shard A │ │ Shard B │
│ (users A-M) │ │ (users N-Z) │
└─────────────┘ └─────────────┘
Cache-Aside Pattern:
1. Check cache for data
2. If miss, read from database
3. Store in cache
4. Return data
Write-Through:
1. Write to cache
2. Cache writes to database
3. Return success
Write-Behind (Write-Back):
1. Write to cache
2. Return immediately
3. Cache asynchronously writes to database
Cache Invalidation:
- TTL-based (simple, may serve stale data)
- Event-based (complex, more accurate)
- Hybrid approach (TTL + event invalidation)
┌─────────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐
│ Browser │───▶│ CDN Cache │───▶│ App Cache │───▶│ Database │
│ Cache │ │ │ │ (Redis) │ │ │
└─────────┘ └───────────┘ └───────────┘ └──────────┘
Cache levels:
// REST API call
const response = await fetch('https://api.service.com/resource');
// gRPC call
const result = await client.getResource(request);
Pros: Simple, immediate response Cons: Tight coupling, cascade failures
// Publish event
await messageQueue.publish('order.created', { orderId, items });
// Subscribe to events
messageQueue.subscribe('order.created', async (event) => {
await processOrder(event);
});
Pros: Loose coupling, resilience Cons: Complexity, eventual consistency
States:
┌────────┐ failures > threshold ┌────────┐
│ CLOSED │───────────────────────▶│ OPEN │
└────────┘ └────┬───┘
▲ │
│ success │ timeout
│ ▼
│ ┌───────────┐
└───────────────────────────│ HALF-OPEN │
success └───────────┘
class CircuitBreaker {
private failures = 0;
private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
private nextAttempt = Date.now();
async call<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'OPEN') {
if (Date.now() < this.nextAttempt) {
throw new Error('Circuit breaker is open');
}
this.state = 'HALF_OPEN';
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
}
| Criterion | Weight | Questions to Ask |
|---|---|---|
| Fit for purpose | High | Does it solve our specific problem? |
| Team expertise | High | Do we have or can we acquire skills? |
| Community/Support | Medium | Active community? Commercial support? |
| Performance | Medium | Meets our throughput/latency needs? |
| Scalability | Medium | Can it grow with our needs? |
| Cost | Medium | Licensing, infrastructure, maintenance? |
| Security | High | Security track record? Compliance? |
| Integration | Medium | Works with our ecosystem? |
| Longevity | Low | Will it be maintained long-term? |
## Technology Comparison: [Category]
### Options
1. Option A
2. Option B
3. Option C
### Comparison Matrix
| Criterion | Option A | Option B | Option C |
|-----------------|----------|----------|----------|
| Fit for purpose | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Team expertise | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| Performance | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Cost | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
### Recommendation
[Your recommendation with rationale]
┌─────────────────────────────────────────────────────────┐
│ Users │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Our System │ │
│ │ │ │
│ │ Manages user accounts, processes orders, │ │
│ │ handles payments │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────┴────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Payment Gateway │ │ Email Service │ │
│ │ [External] │ │ [External] │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Our System │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Web App │───▶│ API │◀───│ Mobile App │ │
│ │ [React] │ │ [Node.js] │ │ [React Nat] │ │
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Database │ │
│ │ [PostgreSQL]│ │
│ └─────────────┘ │
└──────────────────────────────────────────────────────────┘
When this skill is activated, I can help create: