Live · Wed, Jul 22, 2026 · 16:04 UTC Block 843,917 Fees 14 sat/vB Fear & Greed 72 · Greed
Newsletter Pro Terminal Sign in
ITop Field News.
Subscribe →
Live · 16:04 UTC Block 843,917 F&G 72
Software development Software development desk

Event-driven architecture: when it fits and when it doesn't

Event-driven architecture decouples services in ways that can unlock real scalability, but the pattern carries genuine trade-offs that are easy to underestimate. Here is a clear-eyed look at when it earns its complexity.

From below of fiber optic equipment with similar colorful rubber cables and round sockets

Photo by Brett Sayles on Pexels

Event-driven architecture (EDA) has become one of the most talked-about patterns in modern software development, and for good reason. When services communicate by publishing and consuming events rather than calling each other directly, they become far less coupled. But that decoupling comes with a cost, and teams that adopt EDA without understanding the trade-offs often end up with distributed systems that are harder to reason about than the monoliths they replaced.

What event-driven architecture actually means

At its core, EDA means that components communicate by emitting events: discrete, immutable records of something that happened. A payment service doesn't call an order service directly; instead it publishes a PaymentCompleted event to a broker (Kafka, RabbitMQ, AWS EventBridge, and similar tools are common choices), and any interested downstream service consumes it at its own pace. The producer has no knowledge of, or dependency on, what happens next.

This is fundamentally different from a request-response style (REST or gRPC calls), where the caller waits for a reply and both sides must be available simultaneously. EDA introduces asynchrony, which is both the source of its power and the root of most of its complexity.

Where EDA genuinely helps

The pattern earns its place in a few specific situations.

High-throughput, write-heavy workloads

When a system needs to ingest a large volume of state changes quickly without bottlenecking on downstream processing, an event broker acts as a buffer. An IoT platform collecting sensor readings, a fraud detection pipeline processing card transactions, or an e-commerce platform handling flash sale traffic all benefit from the producer-consumer decoupling that EDA provides. Consumers can scale independently, and the broker absorbs bursts without cascading pressure onto dependent services.

Systems that need fan-out

When a single event needs to trigger multiple, independent actions, EDA makes that clean. A UserRegistered event might be consumed by a welcome-email service, an analytics pipeline, and a CRM integration, all simultaneously and without the originating service caring about any of them. In a synchronous design, the registration endpoint would need to call all three services directly, accumulating latency and failure surface with each addition. EDA keeps the originating service simple and makes new subscribers cheap to add.

Long-running or asynchronous business processes

Some workflows span minutes, hours, or days. An insurance claims process, a multi-step onboarding flow, or a build pipeline are not good candidates for a synchronous call chain. Choreographed event flows, where each service listens for the preceding event and publishes the next, model these naturally. Saga patterns, whether choreography-based or orchestrated, are a common implementation approach here and pair well with EDA.

Enabling real-time data streams

If your product or analytics layer needs a continuous stream of state changes, events are the right primitive. This is the domain where tools like Apache Kafka were purpose-built: capturing every change as a durable, replayable log means consumers can rebuild state, backfill analytics, or audit history without hitting the source database. This is a meaningful advantage over polling or change-data-capture hacks bolted onto a relational model.

Where EDA creates more problems than it solves

The pattern is fashionable enough that teams sometimes reach for it when simpler approaches would serve them better. The honest question is whether the operational overhead is justified.

Simple CRUD applications

If your service is a standard create-read-update-delete application with a handful of endpoints and a single database, introducing an event broker adds infrastructure, operational complexity, and cognitive load with almost no benefit. A well-designed monolith or a small set of REST services with a shared database is faster to build, easier to debug, and simpler to operate at low-to-moderate scale. EDA's value grows with scale and fan-out requirements; it rarely makes sense as a default starting point.

When you need strong consistency

EDA is inherently eventually consistent. Events propagate asynchronously, which means there is always a window during which different services hold different views of the world. For use cases that demand immediate read-your-own-writes consistency or where users expect synchronous confirmation of a complete outcome (booking a seat on a flight, submitting a regulated financial transaction), eventual consistency can be genuinely problematic rather than merely inconvenient. Building compensating transactions and idempotency guards to work around this adds significant engineering effort.

Small teams without the operational maturity

Operating a message broker in production requires skills that go beyond application development: schema registry management, dead-letter queue monitoring, consumer lag alerting, partition rebalancing, and event schema versioning are all real operational concerns. Teams that don't yet have solid observability practices in place will find distributed event tracing particularly painful. If you cannot yet trace a synchronous request cleanly across two services, debugging a message that failed silently in an async consumer will be significantly harder.

Tightly coupled workflows disguised as events

A common antipattern is building what is effectively a remote procedure call disguised as an event: one service publishes a command, waits for a reply event, and fails if it doesn't arrive within a timeout. This pattern captures the complexity of EDA (broker infrastructure, async plumbing) without the benefits (decoupling, fan-out, backpressure handling). If your events are really just synchronous calls wearing a message queue as a costume, you have added latency and failure modes without gaining flexibility.

Schema design and the versioning problem

One of the most underestimated challenges in EDA is event schema evolution. Unlike a REST API where you can version an endpoint and force consumers to upgrade, event schemas in a durable broker may be consumed by multiple services at different versions indefinitely. A poorly planned schema change can break consumers silently or cause a consumer to process stale events incorrectly.

The practical disciplines that help here include: using a schema registry (Confluent's registry for Kafka is widely adopted), favouring additive changes over field removal, and documenting event contracts with the same rigour applied to public APIs. Teams who treat event schemas as internal implementation details and change them freely will accumulate versioning debt quickly. This ties closely to the same careful thinking that good API versioning strategies demand in request-response contexts.

Choreography vs orchestration

Within EDA, teams face a secondary architectural choice: should complex workflows be choreographed (each service reacts to events and publishes the next) or orchestrated (a central coordinator issues commands and awaits outcomes)?

Choreography keeps services autonomous and requires no central process engine, but complex workflows become hard to visualise and debug because the process logic is distributed across many consumers. Orchestration (using tools like AWS Step Functions, Temporal, or Camunda) puts the process logic in one place, making it observable and modifiable, but introduces a coordinator that becomes a dependency for every workflow it manages.

Neither approach is universally better. Short, simple fan-out workflows suit choreography. Long-running business processes with error handling, retries, and compensations are usually easier to reason about when orchestrated.

A practical decision framework

Before committing to EDA, a team should be able to answer yes to at least one of these questions: Does the system need to ingest or distribute events at a scale that a synchronous call chain cannot handle? Does a single business event need to trigger multiple, independent downstream reactions? Does the system include workflows that naturally span long durations or require durable state across failures?

If the honest answer to all three is no, EDA is likely adding complexity without commensurate value. Start with the simpler architecture, and move to EDA when the specific pressure points that justify it appear. Building for the complexity you have, not the complexity you imagine, is still the right instinct in software design.

For teams that do commit to EDA, the investment in observability infrastructure, schema governance, and operational runbooks pays down significantly over time. The pattern is powerful when applied to the problems it was designed to solve. The key is recognising when those problems are actually yours.

→ The Confirmations · Daily newsletter

One email at 06:00 UTC. Six minutes. The only digest written for desks, not for retail.