Skip to main content

Distributed Messaging & Event Systems

Messaging systems are the nervous system of distributed architectures, enabling asynchronous communication, decoupling, and event-driven processing. If databases are the “memory” of your system, messaging is the “nervous system” — it carries signals between components without requiring the sender to wait for the receiver to process them, just as your brain can send a nerve impulse to your hand without pausing all other activity until the hand responds.
Module Duration: 14-18 hours
Key Topics: Kafka, RabbitMQ, Event Sourcing, CQRS, Exactly-Once Semantics, Stream Processing
Interview Focus: Kafka internals, delivery guarantees, event-driven architecture

Why Messaging Systems?


Message Queue Patterns

Point-to-Point (Work Queue)

Publish-Subscribe (Fan-out)

Consumer Groups (Kafka Style)


Apache Kafka Deep Dive

Must-Know: Kafka is the de facto standard for event streaming. Expect detailed questions about partitions, replication, and exactly-once semantics.

Architecture

Partition Internals

Producer Delivery Guarantees

Consumer Offset Management

Think of Kafka offsets like a bookmark in a book. If you lose the bookmark, you have to re-read from wherever you last remember — potentially re-reading pages (reprocessing messages). The critical question is: do you move the bookmark before or after you read the page?
Production pitfall: If your consumer group has more instances than partitions, the extra consumers sit idle — they cannot share a partition. Plan your partition count at topic creation time, because increasing it later changes the partitioning of keyed messages and can break ordering guarantees for in-flight data.

Kafka Transactions (Exactly-Once)


Event Sourcing

Pattern Overview

Event Store Implementation


CQRS (Command Query Responsibility Segregation)

Projection Example


Message Queue Comparison


Dead Letter Queues


Advanced Design Scenarios

Scenario 1: End-to-End Exactly-Once Pipeline

You need to build a consume → transform → produce pipeline that processes financial events exactly once, even across restarts and network failures. Requirements:
  • Input events from Kafka transactions.raw
  • Processed events written to Kafka transactions.cleared and a database
  • No duplicate effects (no double-charging, no missing debits)
Design:
  • Use idempotent + transactional producer for the output topic
  • Use read-committed consumers and manual offset commit
  • Wrap DB writes and Kafka offset/produce in a single transaction (per-partition)
Key pattern:
  • Maintain an idempotency key (e.g., event ID) table in the DB
  • On each event:
    • If key seen before → skip (already processed)
    • Else → apply business logic, insert key, produce output message, commit transaction and offset
This gives a practical, implementation-ready story you can walk through at the whiteboard.

Scenario 2: Handling Backpressure and Slow Consumers

You run a high-throughput Kafka topic with occasionally slow consumers. Symptoms:
  • Consumer lag grows during spikes
  • Retention window is threatened
  • Downstream services start timing out
Strategies:
  • Horizontal scale: Increase consumer instances within the group (up to partitions count)
  • Backpressure-aware processing: Use bounded thread pools and queues in consumers
  • Prioritization: Route high-priority messages to a separate topic/consumer group
  • Graceful degradation: Drop non-critical messages or aggregate at coarser granularity under load
Be prepared to discuss lag monitoring, alerting, and how you would safely catch up (e.g., temporary relaxed SLAs, extra consumer capacity, or time-bounded replay).

Scenario 3: Region Outage and Replay

Your system runs active-active in two regions, both consuming from and producing to regional topics. Requirements:
  • If one region fails for 2 hours, you must replay missed events when it comes back
  • No double-processing and no lost events
Design outline:
  • Use per-region topics (e.g., events.us, events.eu) plus a global replication pipeline
  • Keep checkpoints per consumer group and region (last processed offset / timestamp)
  • On recovery:
    • Start consumers from last committed checkpoint
    • Apply the same idempotent processing pattern as Scenario 1
This scenario connects messaging to disaster recovery and business continuity planning.

Interview Practice

Question: Design a system that sends notifications (push, email, SMS) for an e-commerce platform.Design:
Question: When would you choose Kafka over RabbitMQ?Choose Kafka when:
  • High throughput needed (100K+ msg/sec)
  • Need to replay messages
  • Event sourcing / audit log
  • Stream processing (Kafka Streams, ksqlDB)
  • Multiple consumers reading same messages
  • Long-term message retention
Choose RabbitMQ when:
  • Complex routing needed (fanout, topic, headers)
  • Low latency is critical (< 1ms)
  • Need RPC patterns (request/reply)
  • Traditional work queues
  • Smaller scale, simpler operations
  • Need message priority
Key Insight: Kafka is a log, RabbitMQ is a queue. Different mental models! Think of Kafka as a newspaper archive — everyone can read any issue at any time, and old issues stick around based on retention policy. RabbitMQ is more like a postal service — once the letter is delivered and acknowledged, it is gone.
Question: How do you achieve exactly-once message processing?Answer:True exactly-once is impossible (Two Generals Problem). We achieve “effectively exactly-once”:Option 1: Idempotent Consumer
Option 2: Kafka Transactions (EOS)
Option 3: Outbox Pattern
Option 4: Change Data Capture (CDC)

Key Takeaways

Kafka is a Log, Not a Queue

Messages persist, can be replayed, and multiple consumers read independently.

Partitions Enable Parallelism

More partitions = more consumers = higher throughput. Choose partition key wisely.

Event Sourcing Provides Audit Trail

Store events, derive state. Enables debugging, replay, and temporal queries.

Exactly-Once = Idempotency

At-least-once delivery + idempotent processing = effectively exactly-once.

Next Steps

Data Systems

Learn about Kafka’s storage, compaction, and stream processing

Transactions

Understand distributed transactions and the Saga pattern