# Event-driven architecture

> Event-driven architecture connects components through events: records that something happened, such as an order being placed or a video upload finishing. Producers publish events, and consumers react independently, keeping slow downstream work off the request path while introducing delays and new failure cases.

Source: https://sysround.com/concepts/event-driven-architecture
Updated: 2026-11-05


## How event-driven architecture works

Start with a business event, not just a background task. An event such as OrderPlaced states a fact; a command such as SendReceipt asks a particular component to act. An event typically includes an event ID, entity ID, event type, schema version, and the data consumers need.

A producer commits a state change and reliably publishes the corresponding event. Writing the database and publishing to a broker separately creates a failure window. A transactional outbox closes that window by saving the business change and an outbox record in one database transaction, then having a relay publish the record.

A broker routes or retains events for consumers. With publish-subscribe, billing, notifications, and analytics can each receive OrderPlaced through separate subscriptions. Within one subscription or consumer group, multiple workers can share the processing load rather than each processing every event.

Consumers update their own state or trigger more work, then acknowledge successful processing. A crash after a side effect but before acknowledgment can cause redelivery, so handlers need idempotent effects. For database updates, recording the event ID and applying the update in the same transaction is one common approach.

Define ordering only where the business needs it. For example, route an order's events through the same ordered partition, and preserve that order during processing. Include entity versions when consumers must reject stale updates; broker ordering alone does not protect against concurrent processing or reordered retries.

Operate the pipeline as a system with backlog and partial failure. Monitor consumer lag, event age, failures, and end-to-end completion time. Use bounded retries, dead-letter handling, compatible schema changes, and controlled replay; broker retention determines how far consumers can recover.

## Worked example: Keeping order notifications off the checkout path

Suppose checkout accepts 200 orders per second. Each transaction saves an order and an OrderPlaced outbox record. A relay publishes those events to a durable broker, with separate consumer groups for email and analytics. Checkout returns after the database commit, not after email delivery. If the email provider is unavailable for 10 minutes, about 120,000 email events accumulate while analytics can continue. After recovery, email workers process 500 events per second; with 200 new events per second arriving, the backlog drains in roughly 400 seconds. Workers deduplicate by event ID, use provider idempotency when available, and reconcile uncertain send outcomes rather than assuming retries cannot send twice.

## Trade-offs

- **Independent scaling and failure isolation.** Consumers can scale and recover separately, but a broker outage or shared resource bottleneck can still affect multiple services.
- **Shorter request paths, delayed completion.** The API can return after durable acceptance, but downstream results may appear later and need explicit pending states or freshness targets.
- **Loose runtime coupling, lasting data contracts.** Producers need not call every consumer, but event schemas and business meanings become contracts that must evolve compatibly.
- **Reliable delivery requires duplicate-safe effects.** At-least-once delivery supports recovery, but consumers must handle duplicates and uncertain external outcomes without blindly repeating side effects.
- **Ordering limits parallelism.** Serializing work for one entity simplifies correctness, but a hot entity can become a bottleneck even when other partitions have spare capacity.
- **More operational complexity.** Queues buffer bursts rather than create capacity, so teams must manage backlog, poison events, replay safety, and tracing across asynchronous boundaries.

## When to use it in a system design interview

- One committed change must trigger several independent reactions, such as feed updates, notifications, and analytics.
- Slow or unreliable work should not block an interactive request, such as transcoding media or calling an email provider.
- Traffic arrives in bursts, and downstream workers need durable buffering and independently adjustable processing capacity.
- The design needs continuously updated derived views, search indexes, aggregates, or recommendations with an explicit staleness budget.
- A business process spans services and can represent intermediate states instead of requiring one immediate cross-service transaction.

## How to bring it up in the interview

- Identify the synchronous boundary first: explain what must be durable before the API returns and which effects can complete later. Interviewers will probe whether “accepted” is being confused with “finished.”
- Walk through one event end to end, naming the producer, publication mechanism, topic or queue, consumer groups, state changes, and acknowledgment point.
- Defend the failure behavior with a crash example: ask what happens after the database commit, after publication, and after a consumer's side effect but before acknowledgment.
- Specify delivery and ordering scopes rather than promising “exactly once” or “ordered events.” Expect follow-ups about duplicate payments, stale updates, hot partitions, and replay.
- Give an event-age target and a recovery plan. Explain how lag is detected, how throughput catches up, and what happens when a consumer cannot recover before retention expires.

## Common mistakes

- Adding a broker to every interaction, including operations that need an immediate result and are simpler as synchronous calls.
- Publishing an event separately from the database commit without explaining how missing or premature events are prevented.
- Assuming all subscribers receive a copy when they actually share one work queue or consumer group.
- Treating broker delivery guarantees as guarantees that an external side effect, such as a charge or email, happens exactly once.
- Confusing event-driven architecture with event sourcing, or assuming asynchronous events enforce cross-service business invariants automatically.

## Interview questions where it comes up

- [Design a notification system](https://sysround.com/questions/design-notification-system): Business events feed independent delivery pipelines that need durable processing, retries, and duplicate-safe sends.
- [Design a news feed like Facebook](https://sysround.com/questions/design-news-feed): Post events drive asynchronous fan-out into followers' feeds, making publication reliability and delayed visibility central concerns.
- [Design a video streaming service like YouTube](https://sysround.com/questions/design-youtube): Upload and processing-completion events coordinate transcoding stages and determine when a video can be published safely.
- [Design a food delivery app like DoorDash](https://sysround.com/questions/design-doordash): Order, restaurant, payment, and courier events advance a distributed lifecycle that must tolerate retries and partial failure.
- [Design an ad click aggregator](https://sysround.com/questions/design-ad-click-aggregator): Click events drive continuously updated aggregates whose correctness depends on duplicates, late arrivals, and replay.
- [Design Google Analytics](https://sysround.com/questions/design-google-analytics): Collected events flow through independent processing stages for sessionization, aggregation, and analytical storage.
- [Design a price alert system](https://sysround.com/questions/design-price-alert-system): Price events trigger stateful alert evaluation followed by reliable notification delivery across an asynchronous boundary.

## FAQ

### What is the difference between event-driven architecture and a message queue?

Event-driven architecture is a way to organize how components react to changes. A message queue is infrastructure that can support it, but queues also carry commands and background jobs. Publish-subscribe topics and retained event logs are other common building blocks.

### Is event-driven architecture the same as event sourcing?

No. Event-driven architecture describes communication and reactions between components; a service can still store its current state in ordinary database tables. Event sourcing stores an entity's authoritative history as events and derives its state from that history.

### When should you avoid event-driven architecture?

Avoid introducing asynchronous boundaries when the caller needs an immediate answer or a local transaction already solves the problem cleanly. Strict invariants, such as preventing oversold inventory, still need an authoritative concurrency-control mechanism. Events can distribute the resulting changes, but they do not replace that mechanism.

## Related concepts

- [Message queues](https://sysround.com/concepts/message-queues)
- [Publish-subscribe](https://sysround.com/concepts/pub-sub)
- [Transactional outbox pattern](https://sysround.com/concepts/outbox-pattern)
- [Idempotency and idempotency keys](https://sysround.com/concepts/idempotency)


---
SysRound (https://sysround.com) is an AI practice tool for system design interviews: a voice or typed AI interviewer, a shared whiteboard, then feedback on every skill and a model answer. Its feedback is AI-generated and can be wrong.
