What is Event-Driven Architecture (EDA)?

Last updated: July 2026

Event-driven architecture is a design style where services announce immutable facts as events, and consumers react independently. The precision the vendor pages skip lives in two words: an event is an immutable, past-tense fact — OrderPlaced, not PlaceOrder — and the producer neither knows nor cares who reacts. That indifference is the architecture: consumers are added, removed, and broken without the producer changing a line, which is decoupling at its most literal. And EDA is a spectrum, not a religion — a single webhook is event-driven; so is a streaming estate; most healthy systems are hybrids.

Key takeaways

QuestionAnswer
An event isAn immutable, past-tense fact — consumers can react, never decline
Event ≠ commandFacts broadcast to whoever cares vs. imperatives aimed at one handler
The decision ruleProducer’s job done before reactions begin → events; caller needs the answer → request-response
The three flavorsNotification · event-carried state · event sourcing (a storage choice)
The standing billIdempotent consumers, correlation IDs, eventual-consistency UX

One fact, many reactions

// JavaScript — Cloud Code (cloud/main.js)
// Everyday EDA: the write IS the event; consumers react independently
Parse.Cloud.afterSave('Order', async (req) => {
  const order = req.object;
  const becamePlaced = order.get('status') === 'placed' &&
    req.original?.get('status') !== 'placed';
  if (!becamePlaced) return;

  // Consumers of one fact — none knows about the others:
  await Parse.Cloud.httpRequest({          // fulfillment system (webhook)
    method: 'POST', url: process.env.FULFILL_WEBHOOK,
    body: { event: 'order.placed', id: order.id },
  });
  await enqueueConfirmationEmail(order);   // async job queue
  // Live Query pushes the change to every open dashboard automatically
});

One fact — an order became placed — and four consumers, none aware of the others: a fulfillment system notified by webhook, an email job enqueued, analytics counting, dashboards updating over a live subscription. Adding a fifth consumer changes nothing upstream. That is the whole pitch, in one save.

Producers, broker, and independent consumers in event-driven architectureA producer emits an immutable past-tense event to a broker. The broker delivers copies to independent consumers, including a fulfillment service, an email job, analytics, and client dashboards. Consumers can be added or fail independently without the producer changing, and each consumer must handle duplicates idempotently.

OrderPlaced
(immutable fact)

subscribes — producer
never knows

Producer
order service

Broker / channel
topic, stream, or trigger

Fulfillment
(webhook)

Email job
(queue)

Analytics

Dashboards
(live query)

New consumer,
added Tuesday

A producer emits an immutable past-tense event to a broker. The broker delivers copies to independent consumers, including a fulfillment service, an email job, analytics, and client dashboards. Consumers can be added or fail independently without the producer changing, and each consumer must handle duplicates idempotently.

The vocabulary, untangled

The SERP’s terminology chaos, resolved in one table — three message kinds by intention, not transport:

CommandEventQuery
GrammarImperative: ShipOrderPast tense: OrderShippedInterrogative
AudienceOne handlerWhoever subscribedOne answerer
Can be refusedYesNo — it already happenedn/a
CouplingSender knows the handlerProducer knows nobodyCaller waits

Fowler’s warning deserves its quote: beware the passive-aggressive command — an “event” the producer emits while secretly requiring one specific consumer to act. If the flow breaks when that consumer doesn’t respond, it was a command all along, and naming it an event just hid the coupling. (The infrastructure words — broker, router, bus, channel, topic — are near-synonyms for the middle box; the pub/sub entry covers that machinery, of which EDA is the generalizing architecture.)

Event-driven vs. request-response

Request-responseEvent-driven
Time couplingCaller waits — callee must be upFire-and-forget — consumers catch up
The answerReturned to the callerThere is no answer, only reactions
Failure modeImmediate, visible errorResilient — and eventually consistent
DebuggingOne call stackCorrelation IDs across hops
Right forReads, logins, payments — anything the caller needsFacts with independent consumers

The one-sentence rule: if the caller needs the result to continue, request-response; if the producer’s job is complete before any reaction begins, events. Placing the order needs a synchronous answer (“did it succeed?”); everything after — email, fulfillment, analytics — is reactions to a fact, which is why real systems are hybrids by design rather than by compromise.

Fowler’s three flavors — and where event sourcing actually fits

PatternThe event carriesConsumersTrade
Event notificationAn ID and little elseCall back for detailsSimple; callback traffic re-couples
Event-carried state transferThe full relevant stateKeep local copiesNo callbacks; duplication and staleness
Event sourcingIs the system of recordRebuild state by replayPerfect audit; a heavyweight storage commitment

The disambiguation that saves meetings: event sourcing is how one system stores data; EDA is how systems talk. They compose but neither requires the other. One more line the vendors blur: pub/sub delivery forgets — late subscribers miss what fired before they arrived — while streaming (the Kafka-style ordered log) remembers, letting consumers replay from any point; choose by whether history is part of the product.

Choreography vs. orchestration

Choreography (EDA-native)Orchestration
CoordinationServices react to each other’s eventsA coordinator commands each step
The workflow livesNowhere explicitly — emergentIn one visible, debuggable place
CouplingMinimalThe orchestrator knows everyone
Failure handlingCompensating events, distributedCentral retry and error logic

The mirror-image rule shared with the orchestration entry: orchestrate when someone must own the outcome of a workflow; choreograph when producers genuinely don’t care what happens next. Long business transactions across services take the saga shape either way — local transactions chained by events or by an orchestrator, undone by compensations rather than rollback.

Everyday EDA — no broker required

The section the architecture centers never write: most app developers already run event-driven patterns without a message broker in sight. A beforeSave/afterSave trigger is a consumer of data-change events. A webhook is an event crossing company boundaries over plain HTTP. A live query is pub/sub with clients as subscribers. A background job enqueued by a trigger is an event spawning async work. The code tabs above are exactly this stack — the write is the event, the trigger is the router, and the consumers are a webhook, a queue, and a subscription. Dedicated brokers (Kafka, RabbitMQ, NATS — with CloudEvents as the standard envelope) earn their operational weight when event volume, replay, and cross-team contracts demand it; the architecture starts much earlier, and “do I need a broker?” usually answers itself: not yet.

Common use cases

  • Order and payment flows — one fact, many departments: the canonical e-commerce pipeline.
  • Cross-system integration — services owned by different teams reacting without direct calls or shared deploys.
  • Real-time features — dashboards, feeds, and presence as client-facing event consumption.
  • Spiky workloads — queues buffering bursts so consumers drain at their own pace.
  • Audit and replay — streaming logs where “what happened, in order” is itself the product.

Should you go event-driven? A decision matrix

SituationLean
One fact, several independent consumersEvents — the home game
Caller needs the answer to proceedRequest-response, unapologetically
Workflow with an owner and an SLAOrchestration — command the steps
Reactions within one app (email on signup)Triggers + jobs — everyday EDA
Cross-company notificationsWebhooks
High-volume, replayable, multi-team streamsA real broker — now it’s earned

Limitations and trade-offs

  • Debugging loses the call stack. A request that fans into five async hops is traceable only by correlation IDs carried from the first event — retrofit is miserable; wire them from day one.
  • Eventual consistency reaches the UI. The user updates a profile and the next screen shows the old name; either design the UX for it or keep that path synchronous.
  • Duplicates are contractual. At-least-once delivery makes idempotent consumers mandatory — the same contract queues impose, because it is the same machinery.
  • Schemas evolve under consumers’ feet. Events are contracts with unknown subscribers: additive changes only, versioned topics for breaks, and tolerant readers everywhere.
  • Emergent workflows hide. Pure choreography means nobody can point at the business process; when auditors or on-call engineers need to, add the orchestrator.

Event-driven patterns on Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. The everyday-EDA section is its feature list read as architecture: every save is an event, afterSave triggers are server-side consumers with the full JavaScript ecosystem, Live Queries fan facts out to clients over managed WebSockets, webhooks carry them to external systems, and background jobs absorb the slow reactions — the code tabs show the whole loop from one order save. The disciplines this article insists on remain yours (idempotent after-hooks, past-tense thinking, sync where the caller needs answers), while the broker-shaped infrastructure — fan-out, delivery, connection fleets — arrives as platform behavior, and graduating to a dedicated streaming broker later is an addition to this architecture, not a rewrite of it.

Frequently asked questions

What is event-driven architecture in simple terms?

Components announce that something happened — an event — instead of calling each other, and any interested component reacts on its own schedule. Broadcast instead of phone call: the announcer's job ends at the announcement, and listeners come and go without the announcer changing.

What exactly is an event?

An immutable record of something that already happened, named in the past tense — OrderPlaced, PaymentFailed — carrying a payload plus metadata like an ID and timestamp. Because it is a fact about the past, consumers cannot decline it; they can only decide how to react.

What is the difference between an event and a command?

Intention. A command is an imperative aimed at one recipient that may refuse it — ShipOrder. An event is a past-tense fact broadcast to whoever cares — OrderShipped. The trap is the "passive-aggressive command": an event secretly expecting one specific consumer to act, which is a command wearing a costume.

What is the difference between event-driven and request-response?

Coupling in time. Request-response is synchronous — the caller waits, needs the answer, and fails if the callee is down. Events are fire-and-forget — resilient and decoupled, but eventually consistent. The rule: if the caller needs the result to continue, request-response; if the producer's job is done before the reactions begin, events.

What is the difference between EDA and pub/sub?

Level. Pub/sub is a messaging pattern — one delivery mechanism, publishers to topics to subscribers. EDA is the architectural style that typically rides on it, along with queues and streams. Pub/sub is plumbing; event-driven is the design philosophy the plumbing serves.

What are event notification, event-carried state transfer, and event sourcing?

Fowler's three distinct patterns hiding under one name. Notification: thin events, consumers call back for details. State transfer: events carry the full data, so consumers keep local copies. Sourcing: a persistence choice — store every change as an event and rebuild state by replay. The third is how one system stores data, not how systems talk.

What is the difference between choreography and orchestration?

Choreography: services react to each other's events, no central brain — maximal decoupling, but the workflow exists nowhere explicitly. Orchestration: a coordinator commands each step — visible and debuggable, at the cost of a central coupling point. Rule: orchestrate when someone must own the outcome; choreograph when producers genuinely don't care what happens next.

How do you handle duplicate and out-of-order events?

By design, not by hope: brokers deliver at-least-once, so consumers must be idempotent — dedupe by event ID, or write handlers whose repetition is harmless ("set status to shipped," never "toggle"). Ordering is guaranteed only per partition or key; architectures that require global order are fighting their own transport.

When should you use event-driven architecture?

When one fact has several independent consumers, when load is spiky and buffering helps, when systems must integrate without knowing each other, or when an audit trail of changes has value. When not: simple CRUD, reads, operations needing immediate strong consistency, and teams without distributed-systems appetite.

What are the drawbacks of EDA?

Debugging without a call stack — correlation IDs become a day-one requirement; eventual consistency surfacing in UX; schema evolution across independent consumers; duplicate delivery; and a broker to operate. The costs are real and front-loaded, which is why the architecture earns its keep only where its benefits compound.

Related terms

Compare with

Further reading

Ready to build your backend?

Start your project on Back4app in minutes — database, auth, APIs, and Cloud Code included. No credit card required.

Written and reviewed by Back4app Engineering, Back4app Engineering · Published 2026-07-30