Skip to content
man glossary/event-driven-architecture

glossary define event-driven-architecture

Name

Event-Driven Architecture(EDA)

A design style where services publish events (message received, order placed) to a broker and others react asynchronously, instead of chaining calls.

Synopsis

EDA, Event-driven design, Pub/sub architecture, Event-driven messaging

Section

Reliability & scale

Level

practitioner

▍

Reviewed

Route each event only to the services that subscribe

8 / 8

Only agents with the required skill are eligible; the least busy of them wins.

Incoming · 0 left

  1. All 8 conversations have been routed.

Conversation 8 of 8 · Skills-based

wamid…77 · failed(needs status.updated)goes toStatus tracker

Skills: needs status.updated, and only Status tracker has it.

  • Inbox service

    2 of 3 open

    • message.received
    1. Ravi · Is my order shipped?needs message.received
    2. Meera · Change my addressneeds message.received
  • Status tracker

    3 of 3 open

    Full
    • status.updated
    1. wamid…41 · deliveredneeds status.updated
    2. wamid…41 · readneeds status.updated
    3. wamid…77 · failedneeds status.updated
  • Order notifier

    2 of 2 open

    Full
    • order.placed
    1. Order 5521 · placedneeds order.placed
    2. Order 5522 · placedneeds order.placed

Waiting · 1

  1. Order 5523 · placedneeds order.placed
Same 8 conversations, each strategy
StrategyRoutedWaitingSkill mismatches
Skills-based710
Round-robin803
Services stand in for agents and event types for skills. Skills-based routing delivers each event to a subscribed consumer, and a full consumer leaves events waiting in the broker. Switch to round-robin for type-blind delivery.

Conversation 8 of 8, wamid…77 · failed: Skills: needs status.updated, and only Status tracker has it.

Description

What is event-driven architecture?

Event-driven architecture (EDA) is a way of building software in which services communicate by publishing events (immutable facts such as "message received", "status delivered" or "order placed") to a broker, and any number of other services subscribe and react in their own time. The producer does not know who consumes its events or wait for them to finish, which is the opposite of a request-driven design where service A calls B, which calls C, and the whole chain fails if any link is slow.

WhatsApp platforms are a natural fit because the platform itself is event-driven: Meta delivers every inbound message, delivery status and template update as a webhook. A request-driven receiver would verify the payload, then synchronously update the CRM, call the bot, notify the inbox and record analytics before answering. In an event-driven design the receiver verifies the signature, publishes one event per message or status, returns 200 and is done; the inbox, bot, CRM sync and analytics each consume the events independently.

Several patterns live under the EDA umbrella. Event notification sends a small fact and lets consumers fetch details; event-carried state transfer puts everything consumers need in the event; event sourcing stores the events themselves as the system of record. Workflows can be choreographed (each service reacts to events) or orchestrated (one coordinator issues commands). Most WhatsApp backends mix them: choreography for fan-out of inbound events, orchestration for multi-step journeys such as order-to-delivery notifications.

EDA is not the same as a message queue. A queue is a building block that hands each job to one worker; EDA is the architectural decision to let events drive the system, usually built from topics, subscriptions and queues together. Webhook fan-out is one concrete use of it, splitting Meta's single webhook stream to many internal consumers.

Key takeaways

  • Event-driven architecture (EDA) connects services through published events rather than direct calls, so producers never wait on consumers.
  • A WhatsApp integration is event-driven at its edge already: every inbound message and status arrives as a webhook event.
  • Each consumer gets its own subscription, retries and dead-letter queue, so a failing CRM sync cannot block the inbox or the bot.
  • Brokers and Meta's webhooks deliver at least once and not always in order: consumers must be idempotent and partition by conversation.
  • A message queue is one building block of EDA; the architecture is the decision to let events, not call chains, drive the system.

Why it matters

Why does event-driven architecture matter?

Request chains turn every dependency's bad day into your outage: if the CRM takes eight seconds, the webhook handler takes eight seconds, Meta retries, and duplicates pile up. Events decouple the timing. The receiver acknowledges in milliseconds, slow consumers fall behind without slowing anyone else, new consumers (a fraud check, a data warehouse feed) subscribe without touching existing code, and each consumer can apply horizontal scaling independently. The price is new failure modes, such as duplicates, reordering and eventual consistency, that must be designed for up front.

Mechanics

How does event-driven architecture work?

  1. step 1 — Name events as facts with a standard envelope

    Use past-tense types such as whatsapp.message.received, whatsapp.status.delivered and order.placed, wrapped in a consistent envelope (CloudEvents 1.0 is a common choice: id, source, type, time, data).

  2. step 2 — Publish once, at the edge

    The webhook receiver verifies X-Hub-Signature-256, publishes one event per message or status, and returns 200 only after the broker confirms. If publishing fails, return an error so Meta retries. For events born in your database (an order confirmed), use a transactional outbox.

  3. step 3 — Give every consumer its own subscription

    The inbox, bot, CRM sync and analytics each read from their own subscription or consumer group, filtered to the event types they care about, with their own retry policy and dead-letter queue.

  4. step 4 — Design consumers for duplicates and disorder

    Brokers and Meta's webhooks offer at-least-once delivery, so use the event id (a wamid, or wamid plus status) as an idempotency key. Webhook event ordering is not guaranteed either: partition by the customer's wa_id and never move a status backwards when read arrives before delivered.

  5. step 5 — Observe the flow, not just the services

    Carry trace context in event headers, and watch consumer lag per subscription: a growing backlog on one consumer is the early sign of trouble that a request-driven system would have shown as timeouts.

Usage

Event-driven architecture in code

// Edge: verify, turn each message/status into one event, publish, then acknowledge.
app.post("/webhooks/whatsapp", verifySignature, async (req, res) => {
const events = [];
for (const entry of req.body.entry ?? []) {
for (const change of entry.changes ?? []) {
const v = change.value;
const pnid = v.metadata?.phone_number_id;
for (const m of v.messages ?? [])
events.push(toEvent("whatsapp.message.received", m.id, pnid, m.from, m));
for (const s of v.statuses ?? [])
events.push(toEvent(`whatsapp.status.${s.status}`, `${s.id}:${s.status}`, pnid, s.recipient_id, s));
}
}
try {
// broker = your client for Kafka, RabbitMQ, a cloud pub/sub service...
await broker.publishBatch("whatsapp-events", events, { partitionKey: (e) => e.subject });
res.sendStatus(200);
} catch {
res.sendStatus(503); // not published: let Meta retry rather than lose the event
}
});
function toEvent(type, id, phoneNumberId, waId, data) {
return {
specversion: "1.0",
id, // dedupe key for every consumer
type,
source: `/whatsapp/${phoneNumberId}`,
subject: waId, // partition key: keeps one conversation in order
time: new Date().toISOString(),
datacontenttype: "application/json",
data,
};
}
// Consumer: its own subscription, its own retries, idempotent.
broker.subscribe("whatsapp-events", { group: "inbox", types: ["whatsapp.message.received"] }, async (event) => {
if (await processed.has("inbox", event.id)) return; // at-least-once: skip repeats
await inbox.append(event.subject, event.data);
await processed.add("inbox", event.id);
});

The receiver only verifies, publishes and acknowledges; everything else happens in consumers that can fail and retry on their own.

Properties

Event-driven architecture: key facts and limits

Core idea
Producers publish facts; consumers subscribe and react
Common envelope
CloudEvents 1.0: id, source, specversion, type required
Meta webhook delivery
At least once, retried for up to 7 days
Meta webhook order
Not guaranteed, so design for reordering
Webhook payload size
Up to 3 MB per notification
Per-conversation order
Partition events by the customer's wa_id

Caveats

Common mistakes with event-driven architecture

  • Acknowledging before the event is safe

    Returning 200 to Meta and then failing to publish loses the message for good, because Meta will not retry a delivery you acknowledged. Publish first (or write to a durable outbox), then acknowledge.

  • Assuming exactly-once and in-order delivery

    Brokers and Meta deliver at least once, and statuses can arrive out of order. Make every consumer idempotent by event ID, partition by conversation, and make status updates monotonic.

  • Events that are really remote procedure calls

    An event named sendWelcomeMessageNow that only one service can handle is a command in disguise and couples the services again. Publish what happened (customer.opted_in) and let consumers decide what to do.

  • Changing event schemas without versioning

    Renaming a field breaks every consumer you forgot about. Add fields rather than change them, version event types (v2) when you must break compatibility, and keep a schema registry or a documented contract.

Example

Example: One webhook, four independent reactions

A Chennai electronics retailer receives a customer reply, "Is my order shipped?". The webhook receiver publishes whatsapp.message.received keyed by the customer's wa_id and answers Meta in 30 ms. The bot service classifies the intent and publishes order.status.requested; the orders service answers with an event the bot turns into a reply. Meanwhile the inbox shows the thread to agents, and analytics counts the intent. When the CRM sync goes down for an hour that afternoon, its subscription simply builds a backlog and catches up later; customers never notice, and the webhook endpoint never returns an error.

Questions

EDA FAQs

Is a webhook an example of event-driven architecture?
A webhook is an event notification over HTTP, so it is event-driven at the boundary. Whether your system is event-driven depends on what happens next: publishing the webhook as events for independent consumers is EDA, while a handler that calls five services in a row is a request chain.
What is the difference between event-driven architecture and a message queue?
A message queue is a component; event-driven architecture is a design style. Queues usually hand each job to one worker, while EDA typically uses topics or exchanges so one event reaches many independent subscribers, each with its own queue.
Do I need Kafka for event-driven architecture?
No. Any broker with durable topics or subscriptions works, including RabbitMQ, a cloud pub/sub service, Redis Streams or a database outbox for small systems. Choose based on volume, ordering needs, retention and what your team can operate.
How do I keep WhatsApp events in order in an event-driven system?
Partition by conversation and make consumers tolerant of disorder. Use the customer's wa_id as the partition key so one conversation is processed in sequence, and compare timestamps or status rank so a late delivered never overwrites read.
When is event-driven architecture overkill?
When one service does all the work and a single queue would do. A small bot with one consumer gains little from topics and schemas; adopt EDA when several teams or services need to react to the same events.

Notes

Best practices for event-driven architecture

  • Keep the webhook receiver boring: verify, publish, acknowledge. Put business logic in consumers.
  • Give each consumer its own dead-letter queue so one poison event does not stall the others.
  • Store raw webhook payloads for a few days; replaying them into a new consumer is the easiest backfill there is.
  • Start with a few well-named event types; splitting a vague event later is easier than merging dozens.

See InfiQ pricing

Put EDA to work

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.