Event-Driven Architecture
In event-driven architecture, services communicate by emitting and reacting to events rather than calling each other directly. Instead of "Service A calls Service B," it becomes "Service A announces something happened; whoever cares, reacts." This creates extreme loose coupling — but comes with tradeoffs.
Events vs Commands
A Crucial Distinction
- Event (past tense, a fact):
OrderPlaced,PaymentReceived,UserRegistered— something already happened. The publisher doesn't care who listens or what they do with it. - Command (imperative, an instruction):
ProcessPayment,SendEmail,ReserveInventory— directed at a specific service, expecting it to do something.
Events are notifications of facts. Commands are requests to act. Event-driven architecture is built on events — services decide for themselves how to react.
The Event Bus
Pub/Sub Pattern
Publish/Subscribe Decoupling
In pub/sub, the publisher emits events to a topic without knowing who (if anyone) subscribes. Subscribers register interest in topics without knowing who publishes.
- Adding a new consumer requires zero changes to the publisher
- Removing a subscriber doesn't affect anyone else
- Multiple subscribers can react to the same event differently
This is why event-driven is so powerful for extensibility: to add audit logging, just subscribe a new service to existing events. No one else changes.
Event Schemas & Contracts
Why You Need a Schema Registry
When services communicate via events, the event structure becomes a contract. If the Order Service changes the OrderPlaced event schema (renames a field, removes data), all subscribers break.
- Schema Registry: Central store of event schemas (e.g., Apache Avro, Protobuf, JSON Schema)
- Backward compatibility: New versions must still work with old consumers
- Forward compatibility: Old producers' events must work with new consumers
- Versioning:
OrderPlaced.v1,OrderPlaced.v2— support both during migration
Choreography vs Orchestration
When to Use Which?
- Choreography: Best for simple flows, few services, independent reactions. Each service owns its logic. Scales well but gets confusing with many services.
- Orchestration: Best for complex workflows with ordering, compensation (saga pattern), and visibility requirements. Easier to monitor and debug, but the orchestrator becomes a critical path.
- Hybrid: Many real systems use both — orchestration for critical business flows (order fulfillment) and choreography for cross-cutting concerns (analytics, notifications).
Advantages & Challenges
Why Event-Driven?
- Loose coupling: Services don't know about each other — only about events
- Easy extensibility: Add new consumers without changing existing services
- Natural audit trail: Events form a history log of everything that happened
- Independent scaling: Each consumer scales based on its own load
- Failure isolation: One consumer being down doesn't affect others
The Challenges
- Eventual consistency: Data across services is only eventually consistent — not immediate
- Debugging distributed flows: "Why wasn't the email sent?" requires tracing across multiple services
- Event ordering: Messages may arrive out of order; your logic must handle that
- Distributed transactions: No simple ROLLBACK across services — requires saga patterns
- Observability: You need correlation IDs, distributed tracing, and event flow visualization
🏢 Real-World: Netflix Content Ingestion Pipeline
When a new movie or show is uploaded to Netflix, it triggers an event-driven pipeline:
- VideoUploaded → Transcoding service encodes into 100+ formats (4K, HD, mobile, etc.)
- TranscodingComplete → Thumbnail service generates preview images
- ThumbnailsGenerated → Catalog service updates the content library
- CatalogUpdated → Recommendation engine re-indexes
- ContentReady → Notification service alerts subscribers who might be interested
Each service is independent — if the thumbnail service is slow, transcoding isn't affected. New services (like A/B testing thumbnails) can subscribe to existing events without changing anything upstream.
🏢 Real-World: E-Commerce Order Event Flow
An order flows through the system as a series of events:
- OrderPlaced → Payment service charges the card; Inventory service reserves stock
- PaymentProcessed → Email service sends receipt; Analytics records revenue
- InventoryReserved → Warehouse service creates pick list
- OrderShipped → Email sends tracking info; Loyalty service awards points
- OrderDelivered → Review service prompts for feedback; Analytics closes the loop
Notice: the Order service knows nothing about emails, loyalty points, or analytics. It just says "OrderPlaced" and walks away. This is the power of event-driven design.
Interactive: Build an Event Flow
Click services to add them to the event flow. Watch events propagate through the system: