Architectural · Deployment · DWG NO. 058

Event-Driven Architecture

The umbrella style where components communicate primarily by producing and reacting to events, rather than calling each other directly.

TypeArchitectural style
ScopeWhole system
ComplexityMedium–High
Common inMicroservice systems, real-time pipelines, IoT and telemetry platforms

Direct calls tie every component's availability to every other's

In a system built entirely on direct request/response calls, a service can only do its job if every service it depends on is up, right now. As the number of components grows, that web of live dependencies becomes both fragile and hard to reason about — and adding a new consumer of existing data means changing the producer's code.

Producers emit facts; consumers react independently

This is the architectural style, not a single pattern — Publisher-Subscriber (delivery mechanism), Event Sourcing (storing state as events), Saga (coordinating a workflow via events), and Domain Events (in-process reactions) are all specific patterns that live under this umbrella. What ties them together: components emit events describing things that happened, and other components subscribe and react, without either side calling the other directly or waiting on an immediate response.

Event Backbone(broker/bus)Order ServiceInventory ServiceAnalyticspub/sub · saga · event sourcing · domain events

A minimal event backbone tying several patterns together

This is deliberately the smallest possible sketch — the same `bus` primitive shown here is what Publisher-Subscriber, Saga, and Domain Events each build on for their specific purpose.

event-driven-overview.js
const bus = new EventTarget();

// Order Service: emits a fact, doesn't know or care who's listening.
function placeOrder(id) {
  console.log(`orders: placed ${id}`);
  bus.dispatchEvent(new CustomEvent("OrderPlaced", { detail: { id } }));
}

// Inventory Service: reacts independently — this is choreography (see Saga).
bus.addEventListener("OrderPlaced", (e) => {
  console.log(`inventory: reserving stock for ${e.detail.id}`);
});

// Analytics: also reacts independently — this is Publisher-Subscriber fan-out.
bus.addEventListener("OrderPlaced", (e) => {
  console.log(`analytics: logged order ${e.detail.id}`);
});

placeOrder("order-1");
// Adding a third subscriber later needs zero changes to placeOrder.

Trade-offs