Event-Driven Architecture Review Check
LESSON
Event-Driven Architecture Review Check
By the end of this lesson, you will be able to...
Review an event-driven design by checking facts, ownership, topology, delivery, contracts, and operations.
Trace one proposed event from publication to side effects and identify where the design promise can break.
Decide which concerns belong in this application architecture review and which should move to deeper follow-on tracks.
Idea in one sentence: A good event-driven architecture review asks what fact moves, who owns it, what can be repeated or delayed, and which signal will prove the design is healthy.
Core Insight
A checkout team proposes this design:
checkout-service publishes OrderSubmitted
fulfillment-service -> reserves stock
billing-service -> captures payment
email-service -> sends confirmation
analytics-service -> updates order reports
The proposal sounds reasonable:
Publish an event so the services are decoupled.
That sentence is too small for a review.
It hides several questions:
- Is
OrderSubmitteda fact, a command, or a vague notification? - Which service owns the fact?
- Should billing capture payment from this event?
- What if the email consumer receives it twice?
- Can fulfillment replay old events without reserving stock twice?
- What happens when the event schema changes?
- Which signal tells the team that consumers are falling behind?
This lesson is the final review checkpoint before the capstone. It does not add a new event pattern. It gives you a way to connect the patterns you already studied.
The review target is simple:
Turn "we use events" into a defensible design with explicit boundaries, guarantees, and operational evidence.
The Naive Review
The naive review asks only three questions:
Does the producer publish an event?
Do consumers subscribe?
Does the broker deliver it?
Those questions are not useless. They are just too shallow.
They check whether messages move. They do not check whether the design means anything precise.
An event-driven system can move messages and still be broken:
- The event can describe a business fact that has not actually happened.
- A consumer can treat a notification as a command.
- The topology can send one copy when every subscriber needs its own independent copy.
- A retry can repeat an external side effect.
- A replay can corrupt a projection.
- A schema change can keep parsing while changing business meaning.
- Lag can rise without anyone knowing which user promise is at risk.
The better review starts from a concrete path.
Plain meaning:
An architecture review is a structured attempt to find where the design's story stops matching system behavior.
In this scenario:
The team says OrderSubmitted decouples checkout from fulfillment, billing, email, and analytics. The review checks whether each of those consumers can use that event safely.
Technical name:
This is an event-driven architecture review. It is not a broker internals review. It focuses on application-level facts, ownership, contracts, delivery behavior, replay, and operational signals.
The Review Map
Use this compact map when reviewing an event boundary.
| Review question | What you are checking | Common failure |
|---|---|---|
| What moved? | Fact, command, notification, or technical message | A vague event name hides different meanings |
| Who owns it? | Source of truth and publication responsibility | A service publishes a fact it cannot prove |
| Who receives it? | Queue, topic, pub/sub, or log shape | Consumers are accidentally coupled |
| What can repeat? | Delivery, retry, idempotency, and side effects | Duplicate delivery creates duplicate user harm |
| What can change? | Schema and semantic compatibility | Old consumers parse a new event incorrectly |
| What can replay? | Backfill, DLQ, recovery, and projection safety | Reprocessing old facts creates new side effects |
| What can slow down? | Lag, backpressure, dependency limits, user impact | The team sees backlog but not the at-risk promise |
| What is out of scope? | Boundary to deeper tracks | The review turns into a full broker, CDC, stream-processing, or workflow design |
The map is a way to force each design claim into a visible state:
input -> transition -> intermediate state -> decision -> output
If the design cannot survive that trace, it is not ready for the capstone.
A Worked Review Trace
Return to the checkout proposal.
The first review problem is the event name:
OrderSubmitted
Submitted by whom? Is payment accepted? Is stock reserved? Can the order still be rejected?
The team clarifies the business flow:
1. Customer places an order.
2. Checkout validates the cart.
3. Payment authorization is requested.
4. The order becomes accepted only after payment authorization succeeds.
5. Fulfillment should reserve stock only for accepted orders.
Now the review can trace two candidate events.
| Step | Input | Transition | Intermediate state | Decision | Naive failure contrast |
|---|---|---|---|---|---|
| 1 | Customer clicks buy | Checkout validates cart | Cart is valid, but payment is not authorized | Do not publish OrderAccepted yet |
Naive design publishes too early because "submitted" sounds useful |
| 2 | Payment authorization succeeds | Checkout records accepted order | Checkout owns a durable fact: order O-812 is accepted |
Publish OrderAccepted from checkout |
Naive design lets billing or fulfillment infer acceptance |
| 3 | Broker stores OrderAccepted |
Fulfillment, email, and analytics each receive a copy | Consumers know the same fact, but at different times | Use topic or log-style fanout, not a single competing queue | Naive design lets one consumer steal work from another |
| 4 | Email consumer crashes before ack | Broker redelivers the same event | Email may see event_id=evt-812 twice |
Use idempotency key before sending receipt twice | Naive design treats retry as harmless |
| 5 | Analytics projection is rebuilt | Old OrderAccepted events are replayed |
Projection work repeats; user side effects should not | Replay only projection updates, not receipt sends or stock reservation | Naive design replays every consumer as if all work were derived state |
| 6 | New field sales_channel is added |
Old consumers keep reading older fields | Contract has two versions in use | Add optional field and preserve existing meaning | Naive design renames or changes fields in one deploy |
| 7 | Email lag rises after a promotion | Broker shows waiting events | The user promise is delayed receipts, not failed orders | Alert on oldest unsent receipt age and retry rate | Naive design blames the broker dashboard |
The output of this trace is a better event boundary:
OrderAccepted(
event_id,
order_id,
customer_id,
accepted_at,
payment_authorization_id,
total_cents,
currency
)
The event name now says what happened. Checkout owns the fact because checkout records the accepted order. Each consumer receives a copy. Consumers protect side effects with idempotency records. Replay is allowed for projections and reports, but not automatically for external side effects.
So far:
The fact is precise.
The owner is named.
The topology matches the subscribers.
Delivery repetition is expected.
Replay has a boundary.
Compatibility has a migration path.
Operations has a user-facing signal.
Check: Why is OrderAccepted a better review candidate than OrderSubmitted in this flow?
Think first, then reveal.
Answer: OrderAccepted names a durable business fact after payment authorization succeeds. OrderSubmitted is ambiguous: it may mean the user clicked buy, checkout received a request, validation passed, or the order is ready for fulfillment. Ambiguity makes ownership, replay, and side effects unsafe.
Scope Boundaries
A review also needs to know when to stop.
This track reviews application architecture. It should expose deeper risks, but it does not need to solve every deeper subsystem.
Use this boundary table.
| Concern found during review | Keep in this review | Move deeper when... |
|---|---|---|
| Broker topology | Choose queue, topic, pub/sub, or log shape | You need replication, storage, or consumer-group internals |
| Idempotency | Name the side effect and stable key | You need saga compensation or transaction protocol depth |
| Schema evolution | Preserve consumer meaning and migration path | You need registry, CDC, or data governance implementation |
| Replay and backfill | Define safe reprocessing boundaries | You need windows, joins, watermarks, or state stores |
| Process visibility | Decide whether choreography hides too much state | You need workflow runtime or durable scheduler design |
| Operational signals | Connect lag, retries, DLQ, and message age to user impact | You need vendor-specific broker operations |
This boundary protects the capstone. It should synthesize this track, not suddenly require the learner to implement a broker, CDC connector, stream processor, and workflow engine.
Common Confusions
Confusion: A checklist makes architecture mechanical
Why it is tempting:
The review map has rows, so it can look like paperwork.
Better model:
The checklist is a forcing function. It makes hidden claims visible. A good reviewer still follows the specific scenario and asks where this design can fail.
Confusion: Decoupled means consumers do not affect producers
Why it is tempting:
Events remove direct request/response calls, so the producer no longer waits for every consumer.
Better model:
The producer is still coupled to event meaning, compatibility, retention, and operational consequences. If the producer changes a fact's meaning, consumers can break even if they are deployed independently.
Confusion: If replay is available, recovery is solved
Why it is tempting:
Keeping old events feels like a universal undo button.
Better model:
Replay repeats input. It does not know which side effects are safe to repeat. Recovery still needs idempotency, target state, windows, priority, and reconciliation.
Trade-offs and Limits
This review improves design clarity. It forces the team to name facts, owners, side effects, compatibility rules, and signals before production makes the gaps expensive.
It costs time and precision.
A vague event name is fast to publish. A precise event boundary takes discussion. Teams must agree on source of truth, topology, retry policy, schema policy, and recovery behavior.
The review can still miss problems.
It may not reveal a broker partition bug, a storage-engine limit, a bad CDC connector, or a workflow-runtime failure. Those belong in deeper tracks and deeper design reviews.
You can see the review boundary from the kind of question being asked:
- "Should this be a fact or a command?" belongs here.
- "Which consumer group protocol handles rebalance edge cases?" belongs in messaging internals.
- "Can this backfill preserve live-user latency?" belongs here.
- "How do watermarks handle late events?" belongs in streaming infrastructure.
- "Should this process use durable timers?" belongs in workflow or saga design.
The trade-off is useful:
Application-level review gives enough rigor to design safe event boundaries.
It deliberately stops before implementation depth takes over the whole conversation.
Practice
Review this proposed design:
returns-service publishes ReturnUpdated
warehouse-service consumes it to restock inventory
refund-service consumes it to issue refunds
email-service consumes it to notify the customer
analytics-service consumes it to update return-rate reports
The team says:
We will use a topic so everyone gets the event.
If something fails, we can replay the topic.
Write a short review.
A strong answer should include:
- Ask what
ReturnUpdatedmeans. A better fact may beReturnReceived,ReturnApproved, orRefundIssued, depending on the business moment. - Name the owner. The service that records the durable return state should publish the fact.
- Check side effects. Refunds and emails need idempotency keys; analytics projections are safer to replay.
- Check topology. Fanout makes sense if every consumer needs its own copy, but each consumer still owns its own failure behavior.
- Check delivery. At-least-once delivery means duplicate observation is possible, so consumers cannot assume one delivery equals one side effect.
- Check schema. Changing return status meanings can break consumers even if parsing succeeds.
- Check operations. Useful signals include refund retry rate, DLQ error class, oldest return age, restock lag, and user-visible refund delay.
- Set boundaries. Broker retention internals, refund saga compensation catalogs, and stream-processing analytics depth can move to follow-on reviews if they become central.
Check: In the practice scenario, which consumer is safest to replay by default: refund, email, warehouse, or analytics?
Think first, then reveal.
Answer: Analytics is usually the safest default replay candidate because it updates derived reports. Refunds, emails, and inventory changes are user-visible or business side effects, so replay needs stronger idempotency and reconciliation rules before it is safe.
Resources
- [BOOK] Martin Kleppmann - Designing Data-Intensive Applications
- Link: https://dataintensive.net/
- Focus: Use the chapters on logs, derived data, messaging, and consistency to connect event movement with application guarantees.
- [ARTICLE] Martin Fowler - What do you mean by Event-Driven?
- Link: https://martinfowler.com/articles/201701-event-driven.html
- Focus: Revisit the differences between event notification, event-carried state transfer, event sourcing, and CQRS when reviewing event meaning.
- [ARTICLE] Martin Fowler - Domain Event
- Link: https://martinfowler.com/eaaDev/DomainEvent.html
- Focus: Compare a domain event with vague technical messages and commands.
Key Takeaways
- Event-driven architecture review starts by naming the fact, owner, topology, delivery behavior, contract, replay boundary, and operational signal.
- A precise event name should describe a durable business fact that the producer is allowed to publish.
- Delivery and replay are not automatically safe; each consumer must protect its own side effects.
- Compatibility is about business meaning, not only parser success.
- A strong review also knows its boundary: it exposes deeper broker, CDC, streaming, saga, and workflow concerns without turning this track into those tracks.
← Back to Event-Driven Architecture and Streaming Foundations