Architecture Patterns
Choosing an architecture is the highest-leverage decision you make on a project. Get it right and your team ships features for years without drowning in complexity. Get it wrong and you spend eighteen months on a rewrite that was avoidable on day one.
The problem is that most architecture content either floats at 30,000 feet ("microservices are about bounded contexts!") or drowns in implementation details without explaining when or why. This section bridges that gap. Every pattern here includes a decision framework — the specific conditions under which it shines, the conditions under which it becomes a liability, and the migration path if you need to switch.
The Architecture Decision Framework
Before diving into any pattern, ask these five questions about your system:
- Team size and structure — How many engineers? How many teams? Are they co-located?
- Change velocity — Which parts of the system change daily? Which parts are stable for months?
- Scale profile — What needs to scale independently? Read-heavy? Write-heavy? Bursty?
- Consistency requirements — Can you tolerate eventual consistency, or do you need strong guarantees?
- Operational maturity — Do you have monitoring, CI/CD, and on-call in place?
Decision Matrix
| Pattern | Best When | Avoid When | Team Size | Operational Overhead |
|---|---|---|---|---|
| Microservices | Independent team scaling, polyglot needs, different release cadences | Small team, early-stage product, unclear domain boundaries | 20+ engineers | High |
| Event-Driven | Async workflows, audit trails, system decoupling, real-time reactions | Simple CRUD, strong consistency required everywhere | 5+ engineers | Medium-High |
| CQRS & Event Sourcing | Complex domains with audit needs, different read/write scaling, temporal queries | Simple domains, small data sets, teams unfamiliar with eventual consistency | 5+ engineers | High |
| Hexagonal Architecture | Long-lived applications, multiple integrations, high testability requirements | Prototypes, throwaway scripts, very small scope | 2+ engineers | Low |
| Clean Architecture | Complex business logic, framework independence, large codebases | Simple CRUD apps, tight framework coupling is acceptable | 3+ engineers | Low-Medium |
| Domain-Driven Design | Complex business domains, domain expert collaboration, large systems | Well-understood simple domains, purely technical infrastructure | 5+ engineers | Medium |
| Design Patterns | Code-level structure, testability, extensibility, team communication | Over-engineering simple code, pattern hunting | 1+ engineers | Low |
| Cloud-Native | Elastic scaling, resilience, independent deployability, managed services | On-premises only, simple apps, no operational maturity | 5+ engineers | Medium-High |
Concept Map
How the Patterns Relate
These patterns are not mutually exclusive — they operate at different levels of abstraction. Domain-Driven Design is a strategic approach to understanding your problem space. Hexagonal and Clean Architecture are structural patterns for organizing code within a single deployable unit. Microservices is a deployment and team-scaling strategy. Event-Driven is a communication pattern. CQRS and Event Sourcing are data patterns.
The most effective architectures layer these together. A mature system might use DDD to discover bounded contexts, clean architecture inside each service, microservices for deployment, event-driven communication between them, and CQRS for the few services that genuinely need separate read and write models. Design Patterns operate at the code level — they are the building blocks (Factory, Strategy, Repository, Decorator) that implement the internals of every higher-level pattern. Cloud-Native patterns operate at the infrastructure level — they provide the resilience (Circuit Breaker, Retry, Saga), deployment (serverless, containers), and operational strategies that make distributed architectures production-ready.
Learning Path
Architecture patterns build on each other. Learn them in this order to avoid applying distributed solutions to problems that don't need them.
| Order | Pattern | Why This Order |
|---|---|---|
| 1 | SOLID Principles | Code-level foundation — every other pattern assumes you understand SRP, OCP, DIP |
| 2 | Design Patterns | GoF patterns — Strategy, Observer, Factory, Decorator. The vocabulary for the rest |
| 3 | Clean Architecture | Structuring a single application — dependency rule, use cases, boundaries |
| 4 | Hexagonal Architecture | Ports and adapters — isolating business logic from frameworks and infrastructure |
| 5 | Domain-Driven Design | Modeling complex domains — aggregates, bounded contexts, ubiquitous language |
| 6 | Microservices | Decomposing a system into services — only after you've mastered the monolith |
| 7 | Event-Driven Architecture | Async communication between services — events, commands, choreography vs orchestration |
| 8 | CQRS & Event Sourcing | Separating reads from writes, audit logs, temporal queries |
| 9 | Cloud-Native | Designing for Kubernetes, managed services, elastic scale |
| 10 | Functional Programming | Immutability, pure functions, composition — reduces entire classes of bugs |
| 11 | Multi-Tenancy | SaaS architecture — data isolation, tenant routing, feature flags per tenant |
The Golden Rule
Master steps 1–5 before touching 6+. Most teams jump to microservices while their single application is still a mess. The patterns at the top of this list pay dividends at every scale; the patterns at the bottom only pay off at sufficient complexity.
How to Use This Section
Each pattern page includes: a first-principles explanation of the core idea, a TypeScript reference implementation, a decision checklist (should you use this?), common anti-patterns and pitfalls, and a migration guide for introducing the pattern into an existing codebase. Read the patterns that match your current needs first, then read the others to understand the trade-offs you are implicitly making.