Architectural Styles
Monolith, modular monolith, SOA, microservices, serverless, event-driven
Architectural styles represent the macro-level organization of system components and their interactions. The major styles form a spectrum from monolith (single deployable unit) through modular monolith (logical separation, single deployment) and SOA (coarse-grained services with ESB) to microservices (fine-grained, independently deployable) and serverless (function-level units managed by the platform). Each style has a different complexity/autonomy trade-off — microservices maximize team autonomy and independent scaling but require significant operational infrastructure (service mesh, distributed tracing, container orchestration). The right style depends on team size, deployment frequency requirements, and organizational structure (Conway's Law).
Key Points
- Conway's Law: system architecture mirrors communication structure — a team with three sub-groups will build a three-layer architecture regardless of technical rationale.
- Monolith is not an anti-pattern — for teams <10 engineers or early-stage products, a monolith's simpler deployment, debugging, and refactoring experience often outpaces microservices.
- Modular monolith (Majestic Monolith): modules enforce domain boundaries via internal APIs and package visibility rules — enables future extraction without premature distribution complexity.
- SOA used a central ESB (Enterprise Service Bus) for routing and transformation — the ESB became a bottleneck and single point of failure, leading to microservices' peer-to-peer communication model.
- Microservices require the Netflix/Uber level of operational maturity: container orchestration, distributed tracing, service discovery, API gateway, circuit breakers, and CI/CD per service.
- Serverless (Lambda, Cloud Functions) eliminates server management but introduces cold start latency (100 ms–2 s), execution time limits (15 min for Lambda), and complex local development.
- The "Distributed Monolith" anti-pattern: microservices that are tightly coupled (shared databases, synchronous chains of 10 services) — all the complexity of microservices with none of the independence benefits.
- Service granularity heuristics: services should align with bounded contexts, be independently deployable, own their data, and be manageable by a team of 2-8 engineers (two-pizza rule).
| Style | Deployment Unit | Coupling | Scalability | Operational Complexity | Best For |
|---|---|---|---|---|---|
| Monolith | Single artifact | High (in-process) | Vertical; full replica scale-out | Low | Early-stage, small teams, fast iteration |
| Modular Monolith | Single artifact | Medium (module APIs) | Vertical; full replica scale-out | Low-Medium | Growing teams, preparing for future extraction |
| SOA | Per service (coarse) | Medium (ESB) | Per service, limited by ESB | High (ESB ops) | Enterprise integration, existing systems |
| Microservices | Per service (fine) | Low (network API) | Per service, independently | Very High (k8s, mesh) | Large teams, high release frequency, scale at service level |
| Serverless | Per function | Very Low | Automatic, event-driven | Low infra, High app complexity | Event-driven, spiky workloads, glue code |
| Event-Driven | Per consumer service | Low (async events) | Per consumer, decoupled | High (broker ops) | Real-time data pipelines, audit streams |
Real-World Example
Amazon decomposed its retail monolith into services starting in 2001 after Jeff Bezos issued the "API Mandate" — requiring all teams to expose their data via service APIs and communicate only through those interfaces, with no direct database access or back-channel communication. This mandate, enforced by threat of firing, is arguably the genesis of modern microservices culture.