Event-Driven Architecture

In an event-driven architecture, services don't call each other. They emit events and react to events. Looser coupling, more resilience, and a different way of thinking about state.

From requests to events

The traditional way: when something happens, you call the next service directly. The order service calls the payment service, which calls the inventory service, which calls the shipping service. A chain of synchronous calls. If any link breaks, the whole flow fails.

The event-driven way: when something happens, you emit an event. OrderPlaced. Other services that care subscribe and react. The order service doesn't know who is listening. It doesn't wait. It moves on.

The shift in thinking

Events describe facts: "user signed up", "payment captured", "shipment dispatched". They are immutable. They happened. Other services consume them, possibly storing their own derived state.

This is a deep shift. In the request world, you have one shared truth in a database. In the event world, each service has its own view of the world built from events. Loose coupling at the cost of harder reasoning.

Choreography vs orchestration

Choreography. Each service listens for events and reacts. No central coordinator. Decentralized, resilient, but the overall flow is hard to see in any one place.

Orchestration. A central workflow service tells each step what to do. Easier to visualize and debug. Re-introduces coupling to the orchestrator. Tools: Temporal, AWS Step Functions, Camunda.

Most real systems use a mix. Choreography for natural domain events; orchestration for complex multi-step business processes (especially those that need rollback).

EVENT-DRIVEN FLOW Order svc EVENT BUS OrderPlaced Payment svc Inventory svc Email svc Analytics svc
One event, many reactors. The producer doesn't know or care who is listening.

Event sourcing (briefly)

A specific style of EDA: store all changes as events, never overwrite. The current state is derived by replaying events. Powerful for audit, time-travel, and debugging. Heavy in terms of complexity. Pick deliberately.

CQRS (Command Query Responsibility Segregation)

Often paired with event-driven design. Writes (commands) and reads (queries) take separate paths. Writes go through a strict, validated model. Reads come from optimized projections built from events. Lets read and write models evolve independently.

What can go wrong

The senior take Don't make every interaction event-driven. Most calls between services are fine as direct API calls. Save events for cases where decoupling, fan-out, or replay actually pay off. Event-driven everywhere is a recipe for accidental complexity.

Event-driven design is a powerful pattern for building resilient, loosely coupled systems. Used well, it makes new features easier to add (just subscribe to existing events). Used everywhere, it turns a coherent system into an unstructured pile of events. Apply with judgment.