Event-driven architecture has moved from a pattern discussed in architecture documents to a default choice for many distributed system designs. The tooling has matured and the operational patterns are established.
Kafka as infrastructure
Apache Kafka is no longer just a message queue. It is the event streaming platform that many organisations' real-time data pipelines are built on. Confluent's managed Kafka, Amazon MSK, and Azure Event Hubs (Kafka protocol compatible) make running Kafka without managing the cluster yourself a viable option. For organisations that need event replay, stream processing, and multi-consumer architectures, Kafka's offset-based consumption model and durable log storage are the right fit.
Azure Service Bus for.NET workloads
For.NET-heavy Azure-native architectures, Azure Service Bus is the natural message queue choice. It provides reliable message delivery with dead-letter queue support, session-based ordering for correlated messages, and message deferral. The.NET SDK is mature and the Azure Functions trigger for Service Bus makes event-driven function architectures straightforward. For teams that need a message queue without Kafka's operational complexity, Service Bus handles the common enterprise messaging patterns cleanly.
The transactional outbox pattern
The hardest problem in event-driven architecture is maintaining consistency between your database and your message queue. If you update the database and then publish an event, a crash between the two operations produces inconsistency. The transactional outbox pattern writes the event to an outbox table in the same database transaction as the state change, then a separate process reads the outbox and publishes to the message queue. This guarantees at-least-once event delivery without distributed transactions.
CQRS and event sourcing in practice
Command Query Responsibility Segregation and event sourcing are architectural patterns that pair naturally with event-driven architecture. CQRS separates the write model (commands that change state) from the read model (queries that return data). Event sourcing represents state as a sequence of events rather than a current value. Both patterns solve real problems but introduce complexity. The honest assessment in 2023 is that both patterns are appropriate for specific domains (financial systems, audit-heavy applications) and overkill for general CRUD applications where the complexity cost exceeds the benefit.