Architecture Patterns

Event-Driven Architecture

When services communicate through events instead of direct calls, you get decoupling, flexibility, and independent scaling. You also get new problems to manage. This section covers how to make good decisions about when and how to use event-driven design.

What is event-driven architecture?

In a traditional request-response model, Service A calls Service B directly and waits for a response. In an event-driven model, Service A publishes a fact about something that happened, and any number of other services can react to it independently. The producer doesn't know who is listening. The consumers don't need to be available at the same moment the event is produced.

This separation is what makes event-driven design attractive for large platforms. A new service can start consuming an existing event without touching the producer. Different parts of the system can evolve at different speeds. Background work, like sending a welcome email or updating a search index, doesn't need to block the user's request.

But event-driven architecture is not free. You trade direct coupling for a different kind of complexity: event schemas that need versioning and ownership, duplicate message handling, eventual consistency instead of immediate answers, observability across multiple services, and the risk that a complex business process becomes invisible because it's spread across many independent reactions. The goal is to use events where they genuinely help, and not force them where they don't.

Events, commands, and queries are different things

A lot of confusion in distributed system design comes from mixing up three types of messages that have a fundamentally different relationship with time.

An event describes something that already happened. It is a fact about the past. CustomerRegistered, PaymentAuthorized, OrderCancelled. Events are immutable and describe a completed state change. The source system doesn't need to care what anyone does with the information.

A command asks for something to happen in the future. ReserveInventory, CreateShipment. Commands can be accepted or rejected. They have an intended recipient. They are not the same as events, even if they travel over the same broker.

A query asks for information right now. The caller needs an answer. GetCustomerProfile, CalculatePrice. Queries are synchronous by nature. Routing a query through an event broker and polling for the result adds latency and complexity for no benefit.

When these distinctions stay clear, the architecture is easier to reason about. When they blur, you end up with things like events named OrderCreated that secretly expect three downstream services to do specific things in a specific order, and nobody owns what happens when one of them fails.

Orchestration vs choreography

Even when you decide to use events, you still need to choose how the overall process is managed. The two main approaches are choreography and orchestration.

In choreography, each service reacts to events it cares about and publishes new events in response. There is no central coordinator. The overall process emerges from the combined reactions of independent services. This works well when the reactions are genuinely independent: sending a welcome email, updating an analytics counter, syncing a CRM record. Each service can own its piece without anyone else needing to know about it.

In orchestration, a single workflow, process manager, or coordinator owns the flow. It decides what happens next, handles retries, manages timeouts, and triggers compensation if something goes wrong. This is the right choice for complex business processes where step order matters, failures need explicit handling, and someone needs to be able to answer "where is this order right now?"

The practical test is simple: if the process gets stuck, who is responsible for knowing where and why? If the answer is "everyone a little bit," that usually means orchestration is the right tool. If each service can independently handle its own reaction with no effect on anyone else, choreography may be enough.

Choosing between choreography and orchestration

Signal Suggests choreography Suggests orchestration
Step ordering Steps are independent Steps must run in sequence
Failure handling Each service handles its own Compensation logic needed
Process visibility Not needed Business needs to see status
Ownership Each service owns its reaction One owner for the outcome

Articles & Tools

In-depth articles and interactive tools covering event-driven design decisions, patterns, and trade-offs.

EDA Decision Matrix Tool

Interactive flow analyzer. Describe your system's intent, topology, and constraints, and get a concrete recommendation: synchronous API, event choreography, or orchestration. Includes pattern blueprints and preset scenarios.

EDA Orchestration and Patterns

Orchestration vs choreography in practice, five good patterns to follow (outbox, idempotency, schema versioning, event ownership, business vs technical events), five anti-patterns to avoid, and a practical decision guide.

Message Broker Comparison: Kafka vs RabbitMQ vs SQS - coming soon

When to use each broker, ordering guarantees, delivery semantics, and how the choice affects your consumer design.

Domain Events vs Integration Events - coming soon

Why the boundary between domains matters for event design, how to version events across team boundaries, and when to translate between internal and external event schemas.

Event Sourcing vs Event-Driven Architecture - coming soon

Two ideas that are often confused. Event sourcing stores state as a sequence of events. Event-driven architecture uses events for communication. You can use either without the other.

Frequently Asked Questions