Decouple your services, absorb traffic spikes, and never lose an event
Decouple your services, absorb traffic spikes, and never lose an event
LinkedIn in 2010 had a monolith that did everything synchronously: when a user updated their profile, it notified all connections, updated search indexes, and sent emails — all in the same request-response cycle. Average response time: 8 seconds. They built Kafka to fix this.
What Message Queues Solve
When you place an order on Amazon, you don't wait for inventory to update, the warehouse to be notified, fraud to be checked, and the email to send. These happen asynchronously. The order succeeds immediately; downstream systems process it at their own pace.
The Three Problems Message Queues Solve
| Feature | Kafka | RabbitMQ |
|---|---|---|
| Model | Distributed commit log | Message broker |
| Retention | Messages retained for days/forever | Messages deleted after consumption |
| Consumers | Consumer groups; each group reads independently | Competing consumers; each message consumed once |
| Throughput | Millions of messages/sec | Thousands to hundreds of thousands/sec |
| Ordering | Guaranteed within a partition | FIFO within a queue |
| Replay | Consumers can replay from any offset | Not possible — once consumed, gone |
| Routing | Simple (topic-based) | Complex (exchanges, routing keys, binding patterns) |
| Best For | Event streaming, audit logs, analytics pipelines | Task queues, job processing, RPC patterns |
When to Use Each
Kafka: event streaming, replay capability, multiple independent consumers, high throughput. RabbitMQ: work queue (each job processed exactly once), complex routing, or RPC over messaging. For simple reliable job queuing: RabbitMQ or AWS SQS.
1import { Kafka } from 'kafkajs';23const kafka = new Kafka({4clientId: 'order-service',Multiple brokers = high availability. One broker down = others continue5brokers: ['kafka-1:9092', 'kafka-2:9092', 'kafka-3:9092'],6});78// Producer: publish events9const producer = kafka.producer();10await producer.connect();1112await producer.send({13topic: 'order-events',14messages: [{Partition key: all events for a user go to the same partition = ordered per user15key: order.userId, // Partition key — same user's orders → same partition (ordered)16value: JSON.stringify({17eventType: 'ORDER_PLACED',18orderId: order.id,19userId: order.userId,20totalCents: order.totalCents,21timestamp: new Date().toISOString(),22}),23}],24});2526// Consumer: each service has its own consumer groupConsumer group ID: all instances of the same service share one group. Each event processed once per group27const consumer = kafka.consumer({ groupId: 'inventory-service' });28await consumer.connect();29await consumer.subscribe({ topic: 'order-events', fromBeginning: false });3031await consumer.run({32eachMessage: async ({ message }) => {Design for idempotency: network issues can cause the same message to be delivered twice33const event = JSON.parse(message.value!.toString());34if (event.eventType === 'ORDER_PLACED') {35await inventoryService.reserveItems(event.orderId);36// Kafka auto-commits offset on success — won't reprocess37}38},39});4041// Multiple services consume the SAME topic independently:42// inventory-service (groupId: 'inventory-service') → gets all events43// email-service (groupId: 'email-service') → gets all events44// fraud-service (groupId: 'fraud-service') → gets all events
Production Message Queue Patterns
The Outbox Pattern: Why Naive Publishing Loses Events
Without outbox: (1) write order to DB ✅ (2) crash 💥 (3) message never published — inventory never updated. With outbox: (1) write order + outbox record in one transaction (2) crash OK — outbox survives (3) outbox worker publishes — at-least-once delivery guaranteed.
Message queue questions test distributed systems consistency understanding. Key insight: "at-least-once vs exactly-once delivery" and idempotency.
Common questions:
Strong answers include:
Red flags:
Quick check · Message Queues: Kafka, RabbitMQ, and Async Communication
1 / 3
Key takeaways
From the books
Designing Data-Intensive Applications — Martin Kleppmann (2017)
Chapter 11: Stream Processing
The log (Kafka's data model) is one of the most important abstractions in distributed systems. It enables replayability, multiple consumers, and decoupled service architecture.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.