Back to Architecture Patterns
ApplicationEnterprise

Event-Driven Microservices

Decouple everything. Let services communicate through events, not expectations about each other's uptime.

May 2, 2026
|
3 topics covered
Discuss This Architecture
Event-Driven Microservices
Application
Category
Enterprise
Complexity
Financial Services, E-Commerce
Industries
3+
Technologies

When You Need This

Your monolith is becoming a deployment bottleneck — every change requires coordinating across teams, and a bug in billing takes down the entire application. Or you're building a new system where different capabilities evolve at different rates: order management changes weekly, but inventory logic changes quarterly. You need services that can be developed, deployed, and scaled independently, communicating through events rather than synchronous API calls that create cascading failure chains.

Pattern Overview

Event-driven microservices decompose a system into independently deployable services that communicate primarily through asynchronous events. Each service owns its data, publishes domain events when state changes, and reacts to events from other services. This eliminates temporal coupling — Service A doesn't need Service B to be running to do its work. The pattern incorporates CQRS (Command Query Responsibility Segregation) to separate write and read models, event sourcing to capture the full history of state changes, and saga orchestration to manage multi-service transactions without distributed locks.

Reference Architecture

The architecture centers on an event backbone (Kafka, EventBridge, or NATS) that routes domain events between services. Each service has three boundaries: a command handler that processes incoming requests and emits events, a query handler that serves read-optimized projections, and an event processor that reacts to events from other services. A saga orchestrator coordinates multi-step business processes (e.g., order fulfillment) by listening for events and issuing compensating commands when steps fail.

Core Components
  • Event Bus / Broker: Kafka (for high-throughput, ordered events), EventBridge (for AWS-native routing), or NATS (for low-latency). Handles event routing, replay, and dead-letter queuing
  • Domain Services: Each owns a bounded context — Order Service, Payment Service, Inventory Service, Notification Service. Each has its own database (polyglot persistence) and publishes domain events on state change
  • Saga Orchestrator: Manages long-running business transactions. Implements compensating transactions for rollback (e.g., if payment fails after inventory reservation, release the reservation). Can be choreography-based (services react to events) or orchestration-based (central coordinator)
  • Event Store: Append-only log of all domain events. Enables full audit trail, temporal queries ("what was the order state at 2 PM?"), and event replay for rebuilding projections or debugging

Design Decisions & Trade-offs

Choreography vs. Orchestration for Sagas
Choreography (each service reacts to events and emits its own) is simpler for 2-3 step workflows but becomes impossible to reason about at 5+ steps. Orchestration (a central saga coordinator issues commands and tracks state) adds a coordination service but makes the workflow visible and debuggable. MW defaults to orchestration for anything beyond trivial workflows — the operational clarity is worth the extra service.
Event Sourcing: Full vs. Selective
Full event sourcing (every state change is an event, no mutable state) is powerful but operationally demanding — you need snapshot strategies, event versioning, and careful schema evolution. MW applies full event sourcing to domains where audit trail and temporal queries are business requirements (finance, compliance). For other services, we use a simpler "event notification" pattern: services emit events but maintain their own mutable state.
Kafka vs. EventBridge vs. SQS/SNS
Kafka when you need ordered event streams, replay, and high throughput (>10K events/sec). EventBridge when you're AWS-native and want content-based routing with minimal ops. SQS/SNS when you need simple pub/sub without event replay. MW has shipped all three — the choice depends on throughput, ordering requirements, and team familiarity.
Eventual Consistency Communication
Event-driven systems are eventually consistent by nature. MW designs explicit consistency boundaries: within a service, strong consistency (ACID transactions); across services, eventual consistency with idempotent event handlers and at-least-once delivery semantics. We build reconciliation jobs that detect and resolve drift.
Event-Driven Microservices - System Architecture Diagram

System Architecture Overview

Technology Choices

LayerTechnologies
ComputeNode.js (NestJS), Python (FastAPI), Go — per service based on workload characteristics
MessagingApache Kafka (MSK), AWS EventBridge, NATS JetStream, RabbitMQ
DataPostgreSQL (transactional), DynamoDB (key-value), Redis (caching/locks), EventStoreDB
OrchestrationTemporal (workflow orchestration), AWS Step Functions, custom saga coordinator
ObservabilityOpenTelemetry (distributed tracing), Datadog, Jaeger, structured logging with correlation IDs

When to Use / When to Avoid

Use WhenAvoid When
Multiple teams need to deploy independently on different cadencesYour team is < 5 engineers — a well-structured monolith is simpler to operate
Different parts of the system have different scaling characteristicsYou're building an MVP and need to ship fast — distributed systems are slow to build
You need strong audit trails and event replay capabilitiesEvery operation requires synchronous, strongly consistent responses
The domain has natural bounded contexts (orders, payments, inventory)The domain is tightly coupled — splitting it creates a distributed monolith

Our Approach

MW doesn't decompose into microservices by technical layer (API service, data service, auth service). We decompose along domain boundaries using DDD (Domain-Driven Design) bounded contexts. Before writing code, we run an event storming workshop to map domain events, commands, and aggregates — this determines service boundaries, not technology preferences. We've migrated monoliths to event-driven architectures for enterprise clients, and the most common lesson is: start with fewer, larger services and split later, not the other way around.

Related Blueprints

Related Case Studies

Related Technologies
Cloud SolutionsSaaS DevelopmentDigital Consulting

Need Help Implementing This Architecture?

Our architects can help design and build systems using this pattern for your specific requirements.

Get In Touch
Contact UsSchedule Appointment