· software-engineers Editorial · Career · 5 min read
Event Driven Architecture Patterns Comparison
A technical comparison of event-driven architecture patterns — pub/sub, event sourcing, CQRS, and choreography vs orchestration — with tradeoffs and use cases.
The Real Cost of Choosing the Wrong Event-Driven Pattern
Event-driven architecture (EDA) adoption has grown steadily, with the 2026 CNCF Microservices Survey reporting that 71% of organizations running distributed systems now use at least one event-driven pattern in production. But the same survey found that 43% of teams who adopted event sourcing specifically reported regretting the decision within 18 months — not because the pattern is flawed, but because it was applied to problems that didn’t need it. The cost of choosing wrong isn’t abstract: it shows up as unbounded replay times, debugging sessions that span five services, and eventual-consistency bugs that only appear under production load.
This article breaks down the four dominant event-driven patterns, when each earns its complexity budget, and what interviewers are actually testing when they ask you to design one.
Pattern 1: Publish/Subscribe (Pub/Sub)
The simplest pattern: producers publish messages to a topic, consumers subscribe independently, and the broker (Kafka, SNS/SQS, Pub/Sub) handles delivery. No component needs to know about the others.
Best for: decoupling services that need to react to the same event without direct coupling — e.g., an OrderPlaced event triggering inventory update, email notification, and analytics tracking simultaneously.
Failure mode: pub/sub systems degrade into “distributed spaghetti” when teams add implicit ordering dependencies between subscribers without documenting them. If Service B’s consumer silently assumes Service A’s consumer already ran, you have a hidden coupling with no way to enforce it.
Pattern 2: Event Sourcing
Instead of storing current state, you store the full sequence of events that produced it. Current state is derived by replaying events, either on read or via periodic snapshots.
Best for: domains with strict audit requirements (financial ledgers, healthcare records) or where “what happened and when” is itself a first-class product feature.
Failure mode: the most common regret cited in the CNCF survey is applying event sourcing to CRUD-shaped domains that never needed history — a user profile service, for example. Replay cost grows linearly with event count, and without disciplined snapshotting, read-path latency degrades silently over months until it becomes a production incident.
Pattern 3: CQRS (Command Query Responsibility Segregation)
Separates the write model (commands, validation, business rules) from the read model (denormalized, query-optimized projections). Often paired with event sourcing but usable independently.
Best for: systems where read and write load patterns diverge sharply — e.g., a write-heavy order pipeline feeding a read-heavy reporting dashboard that needs different indexing entirely.
Failure mode: teams adopt CQRS for its architectural elegance rather than a measured read/write asymmetry. If your read and write models would look nearly identical anyway, CQRS adds synchronization lag and operational surface area for no benefit.
Pattern 4: Choreography vs. Orchestration for Saga Workflows
When a business process spans multiple services (e.g., checkout: reserve inventory, charge payment, schedule shipping), you need a saga. Two ways to coordinate it:
- Choreography: each service listens for the previous service’s event and emits its own — no central coordinator. Scales well, but debugging a failed saga means tracing across every service’s logs with no single source of truth for “where did this saga break.”
- Orchestration: a central orchestrator (e.g., Temporal, AWS Step Functions) explicitly calls each step and manages compensation logic on failure. Easier to debug and reason about, but the orchestrator becomes a critical dependency and potential bottleneck.
2026 tooling trend: Temporal and Restate have made orchestration the default recommendation for sagas longer than 3 steps, since choreography’s debugging cost compounds faster than orchestration’s coordinator risk.
Comparison Table
| Pattern | Coupling | Debuggability | Best Fit | Common Misuse |
|---|---|---|---|---|
| Pub/Sub | Low | Medium | Independent reactions to one event | Implicit subscriber ordering |
| Event Sourcing | Low | Low (without tooling) | Audit-critical domains | Applied to simple CRUD |
| CQRS | Medium | Medium | Divergent read/write load | Adopted without load asymmetry |
| Choreography Saga | Low | Low | Small (2-3 step) workflows | Used for long, complex sagas |
| Orchestration Saga | Medium-High | High | Long, multi-step business processes | Orchestrator as single point of failure |
How to Decide: A Practical Framework
Before reaching for any of these patterns, answer three questions: (1) Does the read/write load actually diverge, or are you assuming it will? (2) Is historical replay a product requirement, or just “nice to have”? (3) How many services participate in the workflow — under 3, choreography is fine; over 3, orchestrate. Most architecture regret in the 2026 survey data traces back to skipping this three-question filter and defaulting to the pattern that was trending in a conference talk.
System design interviews at senior and staff levels almost always probe this decision framework directly — not “do you know what CQRS is” but “why did you choose it here and what would make you choose differently.” The 0-to-1 SWE Interview Playbook (https://www.amazon.com/dp/B0H256Z1MF?tag=sirjohnnymai-20) walks through exactly this kind of tradeoff reasoning across a dozen system design scenarios, which is the skill interviewers are actually grading.
FAQ
Q: Do I need event sourcing to use CQRS, or can I use CQRS alone? A: You can use CQRS independently. Many production systems separate write and read models using simple database replication or denormalized read-tables updated via change-data-capture, without ever storing an event log. Event sourcing and CQRS are frequently paired because they solve complementary problems, but neither requires the other.
Q: How do I recover from a failed saga in a choreography-based system without a central orchestrator? A: Each service must implement its own compensating action, triggered by listening for a failure event from downstream. This means every service needs both a “do” event handler and an “undo” event handler, and you need a way to guarantee the undo events are actually delivered and processed — typically via the same broker with dead-letter queues and manual replay tooling for cases that fail compensation too.
Q: What’s the single biggest sign that a team over-engineered their event-driven architecture? A: If a new engineer needs more than a day to trace a single business transaction end-to-end across services, the architecture has more indirection than the team can debug efficiently. Distributed tracing (OpenTelemetry) helps, but it’s a symptom fix — the real signal is whether the pattern choice matched the actual complexity of the domain, not the perceived prestige of the pattern.