Browse Event-Driven Architecture Patterns

Pattern Selection Matrix

Decision matrix for matching event-driven patterns to coordination, delivery, and scaling needs.

This appendix is a decision aid for pattern choice. It does not replace the chapter lessons, because pattern selection always depends on trade-offs. What it does provide is a fast way to move from a system problem to the small set of patterns most likely to fit, along with the warning signs that should slow the decision down.

The strongest way to use this matrix is to start from the actual problem shape, not from the pattern you already want to use. Many event-driven mistakes happen because teams begin with “we should use events here” rather than with “what dependency, failure, or scaling problem are we actually solving?”

    flowchart TD
	    A["Start with the problem"] --> B{"Is the problem fan-out, work distribution, reliability, workflow, read modeling, analytics, or governance?"}
	    B --> C["Select a candidate pattern family"]
	    C --> D["Check trade-offs and weak-fit signals"]
	    D --> E["Choose the narrowest pattern that solves the real problem"]

What to notice:

  • pattern selection should begin with the failure mode or dependency shape
  • several problems have more than one plausible pattern, but one is usually a stronger default
  • the weakest decisions usually come from overusing one favorite pattern everywhere

Problem-to-Pattern Matrix

Problem ShapeStrong Candidate PatternWhy It FitsWhat to WatchWeak-Fit Signal
One business fact should trigger many independent downstream reactionsPublish/subscribeIt lets several consumers react independently to the same factSchema stability and fan-out governanceConsumers are not independent and actually need work distribution or a reply
Background work needs to be spread across workersWork queue or competing consumersIt distributes units of work across worker instances efficientlyIdempotency, retries, and hot partitionsSeveral consumers all need the same fact rather than one of them doing the work
State change and event publication can drift apartTransactional outboxIt aligns local commit with later safe publicationRelay monitoring and duplicate publish handlingThe team publishes “after commit” and hopes the broker call never fails
Consumers keep making repeated callbacks to the source service for the same detailsEvent-carried state transferIt improves downstream autonomy by carrying useful state oncePayload growth and contract pressureThe event grows into a producer-internal dump rather than a useful domain contract
One system still needs a response, but messaging transport is already centralCorrelated request/replyIt preserves a request-response shape over asynchronous transportTimeouts, late replies, and correlation stateIt is being used to hide normal low-latency RPC for almost every interaction
A long-running workflow spans several local transactionsSaga with choreography or orchestrationIt models progress and recovery across distributed business stepsCompensation design and visibilityThe team only describes the happy path and has no failure or compensation model
Read concerns need different shapes from write-side correctness concernsProjections or CQRS-style read modelsThey let the read side optimize for query usefulnessReplay safety and eventual consistencyThe read model is quietly being treated as the source of truth
Rolling metrics, joins, or near-real-time insight are neededStream processing with windowsIt supports continuous computation over live event flowEvent-time modeling, state, and backpressureThe problem is simple reporting that a batch job or projection could solve more safely
A few bad events should not block normal processingDead-letter queue or quarantine pathIt isolates repeated failures from the main pathOwnership, diagnosis, and replay disciplineThe DLQ is treated as a trash bin with no review model
Contract changes risk breaking unknown or lagging consumersSchema registry and compatibility checksThey make ownership and safe evolution explicitOverly casual renames and semantic driftThe team still treats event changes like internal refactors
Tenant or data-sensitivity boundaries must be enforcedScoped ACLs, stream governance, and tenant-isolation designThey keep shared event platforms from becoming leakage surfacesOver-broad consume rights and shared-tooling riskTenant ID exists in payloads but no real isolation controls exist

Quick Decision Paths

Some pattern choices repeat so often that short decision rules help.

Use publish/subscribe when one fact should reach many independent consumers. Use a queue or competing-consumer model when one work item should be handled by one worker from a pool. Use event-carried state transfer when callback-heavy notification is preserving runtime coupling. Use correlated request/reply only when a response relationship is truly required and broker-mediated interaction is still useful. Use projections when read shape and read latency matter more than reusing the write model directly. Use a saga only when one business process really spans several local commits and failure recovery must be explicit. Use stream processing when the problem is continuous analytics or rolling computation, not just asynchronous integration.

Pattern Combinations That Often Work Well Together

Some of the strongest event-driven designs combine patterns instead of treating them as mutually exclusive.

  • Transactional outbox plus domain events: strong when business state and reliable publication must stay aligned.
  • Event-carried state transfer plus projections: strong when several consumers need local autonomy and tailored read views.
  • Saga plus orchestration: strong when workflow visibility and compensation discipline matter more than maximum decentralization.
  • Publish/subscribe plus stream processing: strong when operational consumers and analytics both need the same business fact for different reasons.
  • Schema governance plus replay tooling: strong when retained history will be rebuilt or reprocessed over time.

The key is not to combine patterns for sophistication. Combine them only when each one closes a different real risk.

Questions to Ask Before Choosing

Before locking in a pattern, ask:

  • Is the problem mainly fan-out, work distribution, workflow control, read modeling, or continuous analytics?
  • Does the consumer need a fact, a task, or a reply?
  • Does duplicate handling matter at the business-effect boundary?
  • Will retained history or replay make this contract more permanent than the team expects?
  • Is the team choosing a pattern because the problem demands it, or because the pattern feels architecturally fashionable?

These questions often eliminate weak-fit patterns quickly.

Design Review Question

A team says they want one standard solution for all integration, so they plan to use correlated request/reply over the broker for user notifications, batch work dispatch, search aggregation, and normal service reads. What is the strongest challenge?

The strongest challenge is that transport standardization is being mistaken for architectural fit. Those workloads have different dependency shapes. Some need publish/subscribe, some need work distribution, some may need request/reply, and some may still be ordinary RPC. One pattern for everything usually means the actual problem shapes are being ignored.

Check Your Understanding

Loading quiz…
Revised on Thursday, April 23, 2026