Architecture style
Event-driven architecture
Services publish events about what happened, and others subscribe and react. The producer does not know its consumers, so the system is easy to extend.
Command versus event
A command says «do it»: SendWelcomeEmail. An event says «it happened»: UserRegistered. In an event-driven system the registration service just publishes UserRegistered, and the email service, analytics and CRM decide on their own what to do with it.
Adding a new reaction (say, granting bonus lessons) needs no change to the registration service. That is the main benefit: loose coupling between teams and services.
The broker and delivery guarantees
Events go through a broker: Kafka (an event log you can reread), RabbitMQ (classic queues with routing), NATS, Google Pub/Sub. Kafka on an ordinary cluster handles hundreds of thousands of messages per second with single digit millisecond latency.
In practice most systems give «at least once» delivery: the same event can arrive twice. So consumers must be idempotent, for example by storing the event_id of processed events and skipping repeats.
To avoid losing an event between the database write and the publish, use the transactional outbox pattern: the event is written to an outbox table in the same transaction, and a separate process (or Debezium via CDC) sends it to the broker.
The cost of loose coupling
The flow of execution is no longer visible in code: to know what happens after OrderPlaced, you have to find every subscriber. Without an event catalog and tracing through the broker, this quickly turns into chaos.
Data becomes consistent with a delay. A user pays for a course and access appears 1 or 2 seconds later, once the consumer processes the event. The UI has to account for that (a «processing payment» status).
Event schemas live for years, because old consumers rely on them. Version them and check compatibility, for example with a Schema Registry and Avro or Protobuf.
Pros
- The producer does not know its consumers: new reactions need no change there.
- Consumers scale and fail independently, the broker buffers spikes.
- An event is a natural audit log of what happened.
- Analytics and integrations are easy to build on top of the event stream.
Cons
- Logic is scattered across subscribers and hard to follow.
- Eventual consistency: data converges with a delay.
- Requires idempotency, an outbox and duplicate handling.
- Evolving event schemas takes discipline.
When to choose it
- One action triggers many independent reactions (emails, analytics, bonuses).
- Different teams need to react to the same business facts.
- You need a buffer to smooth load spikes.
- You need an event stream for real time analytics or integrations.
Where it is used
- LinkedIn: Kafka was built at LinkedIn as the company's central event log and later open sourced.
Tools
- Apache KafkaKafka is a distributed event log for high-throughput data streaming with durable storage.
- RabbitMQRabbitMQ is a mature message broker with flexible routing through exchanges, acknowledgements and AMQP support.
- NATSNATS is a lightweight, very fast messaging system written in Go with pub/sub, request-reply and the durable JetStream layer.
- Google Pub/SubGoogle Pub/Sub is a global managed messaging service with a publish/subscribe model that scales automatically.
- Apache PulsarPulsar is a distributed messaging and streaming platform that separates brokers from storage and has built-in multi-tenancy.
- Redis StreamsRedis Streams is a Redis data type shaped like an event log with consumer groups, usable as a light message queue.
- Amazon SQSAmazon SQS is a fully managed message queue from AWS that scales automatically and needs no servers.
Related topics
Sources
Logos belong to their owners and are used for identification only. Icons: Simple Icons (CC0), Devicon (MIT).