vishal patel
Applied in productionIntermediateUpdated 2026-09-23

Event-Driven Architecture

Services announce facts ("EntryPublished") and others react asynchronously — decoupling producers from consumers in time, space and knowledge.

eventspub-subasyncdecoupling

The problem

With synchronous calls, the Publish service has to know about and call Search, CDN, Webhooks, Audit and Analytics. Every new consumer changes the producer, and if any one of them is down, publishing fails.

How it works

diagram

The producer publishes a fact in the past tense. It doesn't know who's listening, and adding a consumer needs no change to the producer.

The four flavours (Fowler)

FlavourWhat's in the eventWatch out for
Event notificationJust IDs ("entry 42 changed")Consumers call back for data → hidden coupling and load
Event-carried state transferThe full new stateBigger payloads; consumers keep local copies
Event sourcingEvents are the source of truthSee Event Sourcing
CQRSSeparate write and read models fed by eventsSee CQRS

Design checklist

  • Schema and versioning: add fields, never repurpose them. Use a schema registry for Kafka.
  • Delivery is at-least-once. Consumers must be idempotent.
  • Ordering: only guaranteed per partition or key (e.g. key by entryId).
  • Reliable publish: use the Transactional Outbox to avoid dual writes.
  • Dead-letter queues and replay tooling for poison messages.
  • Correlation IDs in every event so you can trace a flow end to end.
Use it when
  • Many consumers react to the same change
  • Consumers can lag slightly (search, analytics, notifications)
  • You need to absorb traffic spikes by buffering
Avoid it when
  • The caller needs the result right now to continue
  • The team has no tracing or DLQ tooling yet
  • A strict global order of operations is required

Trade-offs

  • ✅ Loose coupling, independent scaling, natural audit trail, resilience to consumer outages.
  • ❌ Eventual consistency: the UI may show stale data briefly.
  • ❌ Harder to reason about. "What happens when X is published?" is spread across the code.
  • ❌ Duplicates, out-of-order events and poison messages have to be designed for.
Where I've used it

In a headless CMS, publishing is inherently event-driven. A publish or release deploy fans out to delivery, CDN and webhooks. The design work was mostly about failure semantics: per-item status, skipping invalid items instead of failing the whole batch, and making redelivery safe.

Cheatsheet

The whole topic on one page. Click to open full screen.

Sources & further learning

Videos, courses, docs and books I recommend for this topic.

Related topics