Architectural Styles Comparison

A synthesis comparing the major architectural styles and patterns covered in this wiki — their core ideas, trade-off profiles, and when to choose each.

The Fundamental Axis: Monolith vs. Distributed

All architectures can be categorized at the highest level:

  • Monolith — all components deployed as a single unit (Layered Architecture is the canonical example).
  • Distributed — components deployed separately, communicating over a network (Microservices, SOA, EDA).

Each category has subcategories. A modular monolith is a middle ground: domain-organized code deployed as one unit.

Style-by-Style Summary

Layered Architecture (N-Tier)

DimensionDetail
Decomposition axisHorizontal (by technical concern: Presentation / Logic / Data)
DeploymentSingle unit (monolith) or separate tiers
CommunicationSynchronous, downward through layers
ScalingScale the whole application (or individual tiers)
Team modelSingle team or feature teams sharing codebase
ComplexityLow operational complexity
Best forEnterprise CRUD apps; teams starting out; clear concern separation needed
Avoid whenHigh domain complexity requiring domain-team autonomy; wildly different scaling per domain

Microservices Architecture

DimensionDetail
Decomposition axisVertical (by business domain)
DeploymentIndependent per service (containers / Kubernetes)
CommunicationSynchronous REST/gRPC or async messaging
ScalingPer-service, independent
Team modelEach service owned by one team
ComplexityHigh operational complexity (container orchestration, distributed tracing, service mesh)
Best forLarge orgs with distinct domains; different scaling needs per domain; many teams in parallel
Avoid whenSmall team; not enough DevOps maturity; unclear domain boundaries

Event-Driven Architecture

DimensionDetail
Decomposition axisBy event type and reaction
DeploymentServices/components + broker infrastructure
CommunicationAsynchronous events via broker (Kafka, RabbitMQ)
ScalingConsumers scale independently from producers
Team modelAny — cross-cuts other styles
ComplexityModerate to high (broker ops, eventual consistency, tracing)
Best forReal-time notifications; IoT pipelines; fan-out scenarios; decoupled microservices
Avoid whenSimple request/response patterns where async adds complexity without benefit

Service-Oriented Architecture

DimensionDetail
Decomposition axisBy business function / capability
DeploymentShared infrastructure with ESB
CommunicationStandardized protocols (SOAP, REST) via ESB
ScalingCentralized infrastructure
Team modelCentral architecture team + service teams
ComplexityHigh governance overhead
Best forLarge enterprises integrating heterogeneous legacy systems
Avoid whenGreenfield projects; small-to-medium organizations; need for high agility

Pattern-by-Pattern Summary

MVC Pattern

Scope: application-level (within a service or monolith). Separates Model (data/rules), View (rendering), Controller (input handling). Entry point for web application structure. Insufficient alone for complex business domains — needs supplementary patterns.

CQRS

Scope: component or service-level. Separates command (write) and query (read) models. Applies when read/write workloads are asymmetric or when read and write models need to evolve independently. Introduces eventual consistency. Frequently paired with Event Sourcing.

Event Sourcing

Scope: persistence strategy. Stores events not state; state is derived by replay. Provides full audit trail and temporal queries. Adds complexity in schema evolution and read-path design. Naturally feeds CQRS projections.

Repository Pattern

Scope: data access within a component. Abstracts persistence behind a collection interface. Enables testability (swap real DB for in-memory). Core building block in Domain-Driven Design, Clean Architecture, and Hexagonal Architecture.

Domain-Driven Design

Scope: approach to complex domain modeling. Provides Bounded Contexts (strategic), and Entities, Value Objects, Aggregates, Domain Events, Repositories (tactical). Best for domains where the business model is the hard part. Natural boundary provider for Microservices Architecture.

Clean Architecture / Hexagonal Architecture

Scope: dependency management between layers. Strict inward-only dependencies (Clean) or inside/outside with Ports and Adapters (Hexagonal). Makes the domain core independently testable. Foundational for DDD implementations.

Decision Guide

Is the domain simple / CRUD-heavy?
  Yes → Layered Architecture (3-tier) + MVC
  No  → Is it a complex business domain?
          Yes → Domain-Driven Design + Layered/Clean/Hexagonal Architecture
               → Add CQRS if read/write asymmetry is significant
               → Add Event Sourcing if audit trail / replay is required

Is the system large with multiple independent teams?
  Yes → Microservices Architecture
       → Use DDD Bounded Contexts to define service boundaries
       → Use EDA for async inter-service communication

Is real-time / event-driven behavior a core requirement?
  Yes → Event-Driven Architecture (pub/sub or streaming)
       → Consider Event Sourcing if events are also the persistence model

Are you integrating large numbers of enterprise legacy systems?
  Yes → Service-Oriented Architecture (or modern API gateway + service registry)

Trade-off Matrix

Style/PatternScalabilityTestabilityOperational ComplexityDeployment AgilityDomain Modeling
LayeredMediumMediumLowLowMedium
MicroservicesHighMediumHighHighMedium
EDAHighLow-MediumMedium-HighHighLow
SOAMediumLowHighLowLow
CQRSHigh (read)HighMediumMediumHigh
Event SourcingMediumHighMediumMediumHigh
Clean/HexagonalN/A (structural)Very HighLowMediumHigh
DDDN/A (approach)HighLowHighVery High