A platform adopts event-driven architecture broadly and finds debugging and reasoning much harder. When is event-driven the wrong choice?
Show the full answer Hide the answer
When it is the wrong choice
1. When the interaction carries an obligation. "Reserve inventory" has an expected effect and someone responsible for it. Published as an event with an implicit consumer, it becomes work with no owner, no acknowledgement, no timeout and no retry policy — so when the consumer is down, orders are accepted, nothing is reserved, and the discrepancy surfaces at fulfilment.
2. When the caller needs the result. Making a request-response interaction asynchronous adds a correlation problem and a waiting state without decoupling anything meaningful.
3. When ordering and consistency matter across several consumers. Events are eventually consistent by construction; if several consumers must agree on state at a point in time, this is the wrong mechanism.
4. When the team cannot operate it. Brokers, partitions, consumer groups, rebalancing, retention, schema evolution and dead-letter handling are a substantial operational surface, and adopting them for a workload a database table would serve is a large permanent cost.
5. When debugging capability does not exist yet. Following a request through an event-driven system requires correlation identifiers propagated across every asynchronous boundary and tracing that covers them. Without those, the system is genuinely hard to reason about — which is the symptom described.
Where it is right
Notifications with many independent consumers. "Order placed" consumed by analytics, search indexing, recommendations and marketing. The publisher does not care who listens, consumers are added without changing it, and a consumer failing delays only its own work.
The rule that resolves most of it
Orchestrate obligations; choreograph notifications.
The design tell: if the publisher would want to know that a consumer failed, it is a command wearing a notification's clothes — and it needs an owner, an acknowledgement and a timeout, which means an orchestrator rather than a topic.
What must be built regardless
Correlation identifiers through every asynchronous hop, tracing that spans them, schema compatibility enforced as a build gate, dead-letter handling with visibility, and idempotent consumers — because at-least-once delivery means every consumer will occasionally process the same event twice.