Architectural Patterns
Most real systems on AWS are built from a small set of recurring patterns — microservices, event-driven, serverless, multi-region. A pattern is shared vocabulary plus shared trade-offs: when it fits, when it does not, what it costs, what it buys you.
The danger is treating patterns as recipes to copy without judgment. A pattern that works at one scale or team size hurts at another. Use them as starting points you adjust to your context.
Microservices and Event-Driven
Microservices trade operational complexity for independent deployment, scaling, and failure. The honest rule: start with a well-structured monolith and move to microservices when it hurts — many teams move too early and pay the operational tax for years. On AWS: ECS/EKS, ALB, per-service RDS or DynamoDB, X-Ray tracing.
Event-driven architecture trades synchronous simplicity for loose coupling, resilience, and replay; eventual consistency, debugging difficulty, and ordering/idempotency are the costs. EventBridge or SNS for the bus, SQS for durable buffering, Lambda for consumers — EventBridge + SQS + Lambda is the canonical lightweight setup.
Serverless, CQRS, and Saga
Serverless (Lambda, API Gateway, DynamoDB, S3, Step Functions) is the right default for new APIs and event-driven workloads — no idle cost, automatic scaling, fast iteration — with cold starts, hard limits, and high-steady-throughput economics as the trade-offs. CQRS separates write and read models; adopt it when read and write shapes genuinely diverge, not on day one.
Saga handles distributed transactions across services as local steps plus compensating actions, usually orchestrated by Step Functions. Reach for it when a business operation crosses service boundaries and must eventually succeed or roll back as a unit.
Strangler Fig and Multi-Region
Strangler Fig is the safe migration pattern: put a routing layer (CloudFront, API Gateway, ALB) in front of the legacy system, replace it feature by feature, and retire it once it has no traffic. Each step is incremental and reversible.
Multi-Region has four flavors by complexity and cost: backup-and-restore (hours), pilot light (tens of minutes), warm standby (minutes), active-active (immediate). Warm standby is the practical DR default; active-active is for genuine global scale. The hardest part is the data model, not the infrastructure.
Well-structured monolith — the right starting point — one deployment, simple operations, no network latency between modules.
Microservices — independent deployment and scaling once the monolith hurts; pays an operational tax that is real from day one.
Strangler Fig — the migration path between them — replace the monolith piece by piece behind a routing layer.
- Adopting microservices before a monolith hurts, paying the operational tax for years with no proportional benefit.
- Adopting CQRS or event sourcing on day one, adding architectural complexity before measurements justify it.
- Treating eventual consistency in event-driven systems as free — ordering, duplicates, and debugging difficulty are real costs.
- Jumping to active-active multi-Region when warm standby (or no multi-Region at all) would meet the requirement.
- Copying a pattern as a template instead of adjusting it to your scale, team size, and constraints.
- Building a 'logic' microservice that owns no data, which adds latency and complexity with no clear ownership.
- Start with a well-structured monolith; move to microservices when it measurably hurts.
- Default to serverless for new APIs and event-driven workloads; use containers for long-running or limit-bound work.
- Use EventBridge + SQS + Lambda as the canonical event-driven setup, with a dead-letter queue per consumer.
- Use the Strangler Fig pattern for monolith migrations — route around and replace incrementally.
- Choose the cheapest multi-Region flavor that meets RTO/RPO; warm standby is the usual DR default.
- Reach for CQRS and Saga only when measurement (or a genuine cross-service transaction) demands them.
Knowledge Check
What is the honest rule about microservices?
- Start with a well-structured monolith and move to microservices when the monolith hurts
- Always start with fine-grained microservices for any new system
- Never use microservices — a single monolith always wins at scale
- Split into exactly seven independent services regardless of the shape of the problem domain
Which multi-Region pattern is the practical default for disaster recovery?
- Warm standby — a scaled-down full version always running, with single-digit-minute RTO
- Active-active across every Region at all times, for every production workload without exception
- Backup and restore, as the default for any production workload
- Multi-Region architecture is never worth the added cost
On AWS, how is the orchestrated Saga pattern usually implemented?
- With Step Functions — each Task calls a service, with compensating actions on failure
- With a single large Lambda function holding the whole multi-step transaction in memory
- With DynamoDB transactions spanning services across Regions
- With CloudFront cache behaviors coordinating each step
When should CQRS be adopted?
- When read and write workloads have different shapes and metrics justify the complexity — not on day one
- On day one of every new application, splitting into separate read and write models before any traffic arrives or any access pattern is known
- Only for static websites served entirely from S3 and CloudFront with no dynamic write path at all
- Never — splitting reads from writes into separate models is always an anti-pattern that adds needless complexity
You got correct