Pattern
Event-driven architecture
Problem
Tight coupling between services makes evolution painful. When service A directly calls service B, they must deploy together, know each other's contracts, and B's failures propagate to A.
Context
You have a domain where things happen (user registered, order placed, payment received) and multiple services need to react.
Solution
Instead of A calling B, A publishes a domain event ('order placed'). B subscribes to the event and reacts. A doesn't know B exists. Adding C is trivial — subscribe to the same event. Services communicate exclusively through events, not direct calls.
Trade-offs
- Debugging is harder — you follow event chains, not call stacks
- Eventually consistent by default — no immediate feedback on downstream failures
- Schema evolution requires event versioning (adding a field is easy; renaming is hard)
- You need a durable event log (Kafka) — significant infra investment
Failure modes
- Event schema mismatch — producer added a field, consumer breaks. Mitigate with schema registry.
- Dead event: no subscriber processes it, no error surfaces
- Ordering assumptions: consumer assumes events arrive in order; sometimes they don't
When to use
- Multiple services that react to domain-level facts
- Loose coupling is more important than synchronous feedback
- You need to add analytics/monitoring/audit consumers without touching producers
When NOT to use
- Simple request-response flows (user clicks → response back)
- Strong consistency requirements between services
- Team is unfamiliar with event-driven paradigms