# ⚖️ Cheatsheet: Kafka vs RabbitMQ: Choose the Right Broker for Your Use Case

> This cheatsheet is part of the paid section. Sign in and purchase the course to view the full content.

One-line model: ==Kafka is a replayable log; RabbitMQ is a broker-managed queue with a routing graph.== Pick the storage model that matches how you need to consume.

---

## Module 1: Architecture and delivery semantics

### 1.1 Log vs queue: what each broker really stores

| Dimension | Kafka | RabbitMQ |
| --- | --- | --- |
| Storage unit | Append-only partition log | Broker-managed queue |
| Consumer position | Client-side offset (consumer owns it) | Broker-side delivery state (unacked set) |
| After consumption | Message stays until retention expires | Message removed once acked |
| Replay | Yes, seek any offset within retention | No, once acked it is gone |
| Fan-out | Free: N consumer groups read same log | Costly: one copy per queue |
| Retention driver | Time/size, independent of consumers | Driven by consumption |
| Delete on consume | No | Yes (default) |

- Kafka retention is decoupled from consumption: a slow consumer does not slow the log.
- RabbitMQ queue length is a pressure signal: backlog lives in the broker, watch memory.
- Replay is Kafka's killer feature. If the answer is "we might need to reprocess", the answer is Kafka.

### 1.2 At-most-once vs at-least-once, worked through both brokers

> [!IMPORTANT]
> Delivery semantics are not a broker switch. They are the position of one line of code relative to your business logic.

**Kafka: the decision is `commitSync`**

```java
// at-most-once: commit BEFORE processing
while (true) {
  ConsumerRecords<String,String> recs = consumer.poll(Duration.ofMillis(100));
  consumer.commitSync();          // offset advanced first
  process(recs);                  // crash here = lost messages
}

// at-least-once: commit AFTER processing
while (true) {
  ConsumerRecords<String,String> recs = consumer.poll(Duration.ofMillis(100));
  process(recs);                  // crash here = redelivery
  consumer.commitSync();
}
```

**RabbitMQ: the decision is `basic.ack`**
