chevron_left Back
Architecture • 12 October 2026 •

Event-Driven Architecture: When to Use It and How to Avoid the Integration Complexity It Creates

Key takeaways

  • Events pay back when several consumers react to the same fact or systems must scale and fail independently. A request that needs an answer now still belongs in a synchronous API.
  • The recurring costs are ordering, duplicate delivery, schema changes and slow replay. Each has a standard control: partition keys, idempotent consumers, a schema registry and snapshots.
  • Platform choice trades control against operational effort and cost, and the skills a team already has often tip the decision.
  • Migrate in steps behind an adapter and trace each business transaction with one ID. Internal streams stay apart from anything shared with third parties under the Data Act.

A synchronous call chain makes every service as slow and as fragile as its weakest dependency. An order service that waits in turn on the payment and stock services inherits both of their bad days, and a timeout three hops away can surface as a failed checkout.

Event-driven architecture (EDA) takes that coupling away and charges for it elsewhere. Messages arrive out of order and handlers run twice. A single business transaction ends up spread across a dozen consumers. Some systems come out ahead on that trade and others lose by it. This article sorts out which is which, and the last section covers what the EU Data Act means for streams shared outside the company.

When event-driven architecture beats synchronous APIs

An event is an immutable fact about the past, such as „the order has been placed.” The producer publishes it and moves on, without knowing which services react.

EDA suits distributed systems that need real-time responsiveness and scalability, with loose coupling between the parts. A synchronous chain gives you the opposite. A slow dependency stalls every caller upstream, and one failing service can take down those that depend on it. Every new consumer means a change to the producer, and throughput tops out at the slowest participant on the call path. With events, consumers subscribe without touching the producer, and the producer no longer waits for any of them.

A price lookup or a credit check needs an answer now. Wrapping it in events adds latency and moving parts for little return. Events earn their place where several consumers react to one fact. Bursty load and teams that release at different speeds point the same way.

The complexity event-driven architecture introduces and how to manage it

Asynchronous communication moves failures out of the call stack and into the spaces between services, and four problems keep coming back.

Ordering is the obvious one. Messages can arrive in a different order than they were created, especially when consumers process in parallel. On a broker with partition ordering, events for one entity stay in sequence as long as they share a partition key. Late and duplicated messages still get through, though, so consumers have to know which state transitions are valid. State machines and saga patterns define them, including what happens when an event arrives at the wrong moment.

Duplicates are next. Exactly-once delivery is hard to rely on in a distributed system, so applications need protection of their own. Message IDs and idempotent consumers make repeated processing safe. Kafka’s exactly-once features (idempotent producers and transactions) cover reads and writes inside Kafka only. A database write or an API call made by the consumer sits outside that transaction and can repeat after a crash. Upserts keyed on a primary key are the usual remedy.

Schemas drift too. When services run different versions of one event, a field change can break consumers the producing team never heard of. A schema registry checks compatibility between versions, which cuts the risk of breaking consumers that are already running.

Event sourcing keeps every change, which gives a full history. Rebuilding the current state gets slower as events pile up, though, and CQRS with periodic snapshots spares the system a replay of the whole history.

None of these controls is free, so apply them where the domain needs them. Event sourcing in a domain that never looks at its history pays the replay cost for nothing.

How to choose between Kafka, Pulsar, RabbitMQ and cloud-native services

The choice depends on the system’s requirements and traffic, and on how much infrastructure the team is willing to run. Kafka is the common pick for high-throughput systems that need durable event logs and scalability, and it has a large ecosystem. Pulsar offers similar capabilities with a different architecture that separates storage from processing, which helps when the two need to scale independently. RabbitMQ is easier to set up and suits traditional messaging and task queues, but very large event streams are a weaker fit. Cloud-native services reduce the infrastructure the team maintains. Amazon Kinesis, Google Pub/Sub and Azure Event Hubs are the usual examples.

Control, scalability, operational complexity and cost pull in different directions. Self-managed platforms give the most control and demand the most work in deployment, monitoring, upgrades and failure handling. Managed services are easier to operate. They can cost more and tie the architecture to a cloud provider.

What the team already knows counts too. A familiar platform simplifies development and maintenance, and that often outweighs a feature comparison.

A migration path for brownfield environments

These choices usually get made with synchronous integrations already in place. Swapping them all out at once is the riskiest way to adopt events, and a gradual migration is safer.

Start by identifying the existing services that gain the most from events, then introduce an event broker with an adapter between the new event-driven services and the old synchronous systems. Existing services keep using their APIs, while selected operations start publishing events that other services consume.

For a while, both communication models run side by side. A step adds one component or moves one dependency, which keeps it small enough to test and correct while the application keeps running. More dependencies move from APIs to events as the migration goes on, until the old integrations have no callers left and can be retired. The adapter is the one place that knows both models, so keep it thin. Logic that piles up there becomes the next legacy system.

How to trace a business transaction across ten async event handlers

During a migration a request can cross both communication models, which makes it harder to follow. When ten handlers process one business transaction, no single log file holds the story. Give the transaction one trace ID where it starts and pass it along with every event, as a message header. Each handler then opens its own span under that trace, and the tracing system shows the whole path, meaning which handlers ran in what order and where the time went. OpenTelemetry is the usual way to implement this.

Put the same identifiers in the logs: trace ID, event ID, handler name and the business identifiers that support teams search by, such as an order number.

Four metrics show the health of the asynchronous parts: processing time, retries, consumer lag and dead-lettered messages. Rising consumer lag warns that a handler is falling behind before any user notices, and a growing dead-letter queue holds events that failed every retry and now need a person. With these in place, a failure several steps downstream leads back to the original transaction.

How the Data Act affects event streams shared with third parties

Events that cross the company boundary add a regulatory question to the technical ones. The Data Act (Regulation (EU) 2023/2854) applies for the most part from 12 September 2025, and its design requirements for connected products and related services follow on 12 September 2026. Under it, users can access the data their connected products and related services generate. The data holder must make it available to them free of charge, and the user can ask the holder to pass it to a third party. In business-to-business sharing the holder provides access on fair, reasonable and non-discriminatory terms, with protections for trade secrets.

A stream that carries product or service data becomes a delivery channel for these obligations. Mixing it with internal events makes control harder. Keep internal streams apart from the data exposed to third parties, so that sharing is always a deliberate decision. Put access control in front of the external streams, and make sure they can serve access and portability requests. Anything that should not be exposed gets filtered or masked before the event leaves the company, and audit logs show who received which data and when.

Not every stream falls under the regulation. Events that describe business activity, such as an order placed, may sit outside the product-data rules, and the line depends on whether the data comes from a connected product or a related service. Settle the scope with legal counsel early, since it decides which topics need the extra controls.

FAQ

What problems does event-driven architecture solve that synchronous APIs do not?

It resolves cascading failures and performance bottlenecks, and it loosens the dependencies between systems. A producer publishes a fact once and any number of consumers react independently, so a slow consumer cannot stall the producer. Requests that need an immediate answer still suit synchronous APIs.

How do you handle event ordering and duplicate delivery?

Use a consistent partition key to keep events for one entity in order, and state machines or sagas to handle transitions that arrive at the wrong time. Make consumers idempotent with message IDs, because exactly-once delivery cannot be relied on across a distributed system.

How do you choose between Kafka, Pulsar, RabbitMQ and cloud-native streaming?

Control, scalability, operational effort and cost pull against each other, and what the team already knows often settles it. Kafka is the usual pick when you need high-throughput durable logs. RabbitMQ is easier to set up for traditional messaging and task queues, and Pulsar separates storage from processing. Kinesis, Pub/Sub or Event Hubs take part of the infrastructure off the team’s hands.

How do you migrate a brownfield system to event-driven architecture?

Migrate gradually. Add a broker and an adapter between the synchronous systems and the new event-driven services, publish events from selected operations, run both models in parallel and move dependencies to events step by step.

How do you trace a business transaction across asynchronous event handlers?

Create one trace ID per business transaction and pass it with every event. Each handler gets its own span, for example with OpenTelemetry. Log the trace ID, event ID, handler name and business identifiers, and watch processing time, retries, consumer lag and dead-lettered messages.

How does the Data Act affect event streams shared with third parties?

Keep internal streams separate from data exposed externally, enforce access control, support access and portability requests, mask data that should not leave the company and keep audit logs of who received which data and when. Whether a stream is in scope depends on whether its data comes from a connected product or a related service.

Joanna Maciejewska Marketing Specialist

Related posts

    Blog post lead
    Architecture Compliance Data

    Data Mesh vs. Data Warehouse: A Decision Framework for Enterprise Architecture Teams

    Key takeaways A central data team drowning in backlog requests points to an architecture problem: business domains have outgrown the data warehouse model built for them years earlier. Enterprise architecture teams evaluating data mesh are making a structural decision about how the organization owns and moves data. The stakes are measured in weeks: how long […]

    Blog post lead
    Architecture Data FinOps Technology

    Real-Time Analytics Architecture: When to Use Streaming and When Batch Is Still the Right Answer

    Key takeaways Every week, a team somewhere decides to rebuild a working batch pipeline as a streaming system. The trigger is usually a stakeholder request for real-time data. The definition of real-time and its actual cost rarely get discussed before the rebuild starts. Six months later, the team is managing Kafka offsets and watermark configurations […]

    Blog post lead
    Architecture Cloud Data Platform Technology

    How to Build a Data Platform That Will Not Become Technical Debt in 18 Months

    The average data platform project starts with genuine ambition and ends with a refactoring budget nobody planned for. In our experience, the architectural decisions that cause the most damage aren’t the ones that look obviously wrong at the time. They’re the ones that look like reasonable shortcuts. What we’ve learned from building and inheriting data […]

© Copyright 2026 by Onwelo