---
title: "Kafka stretched cluster across two data centers"
description: "One Kafka cluster, RF=4 across DC-A and DC-B. While the ISR spans both sites, acks=all writes are durable in both, so losing DC-B costs no committed records."
url: https://monedula.dev/kafka-simulator/scenarios/stretched-cluster-2-dc/
---

# Kafka stretched cluster across two data centers

Scenario 09.1.1 · Stretched cluster across 2 DCs. Disaster recovery · Advanced · about 3 min · Apache Kafka 4.3.

One cluster, RF spread across two DCs: while the ISR spans both sites, an acks=all write is durable in both, so it survives losing a whole DC.

Run it: https://monedula.dev/kafka-simulator/playground/?scenario=09.1.1

## What you start with

A single logical Kafka cluster is stretched across two data centres, with an acks=all partition’s RF-4 replicas placed evenly so the in-sync replica set (ISR) spans both sites. Because a committed write must reach the ISR before the producer is acked, every record is durable in both DCs the instant it commits, as long as the ISR spans both sites. We then lose the follower DC to watch the ISR shrink to the min.insync.replicas floor while a fresh write still commits.

## Step by step

1. **Stretched 2-DC cluster ready - RF 4 across DC-A + DC-B** (t+0.000s): One logical cluster, brokers split 2-and-2 across DC-A and DC-B. The orders partition has RF 4, so a replica lives on every broker - the replica set spans both data centres. A controller voter sits in each data DC plus a witness in dc-c, keeping the quorum odd. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=09.1.1&t=0)
2. **O1 committed - leader in DC-A, ISR spans both DCs** (t+3.050s): p1 produces with acks=all. The record only commits once the full ISR has it, and the ISR includes replicas in BOTH DCs - so the moment p1 is acked, O1 is already durable in DC-A and DC-B. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=09.1.1&t=1)
3. **O2 committed - log {O1, O2} on all 4 replicas** (t+6.050s): A second acks=all write. Both records are now replicated cross-DC to all four replicas; the leader's high-watermark has advanced past both. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=09.1.1&t=2)
4. **DC-B lost - ISR shrinks to the 2 DC-A replicas (= min.ISR)** (t+9.050s): kill_dc drops both DC-B brokers. The leader sits in DC-A so leadership is untouched; the ISR just sheds the two DC-B copies, settling at the 2 DC-A replicas - exactly min.insync.replicas, so the partition is still writable. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=09.1.1&t=3)
5. **O3 accepted - the acked log survived losing a DC** (t+12.050s): A fresh acks=all write still commits on the DC-A leader (ISR 2 = min.ISR), and O1/O2 are intact. Because the write had been durable in both DCs, losing one cost no acknowledged data. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=09.1.1&t=4)

## The takeaway

Stretching one cluster across two DCs gives synchronous cross-site durability while the ISR spans both sites: acked data already exists in both, so losing a DC costs no committed records. Only a min.insync.replicas above the replicas in one DC (3 here) guarantees it; at 2, an ISR shrunk to DC-A keeps acking single-site writes like O3.

## Configs in this scenario

- [`acks`](https://kafka.apache.org/43/configuration/producer-configs/#producerconfigs_acks): How many replicas must have a write before the producer counts it as sent: 0 (none), 1 (the leader only) or all (every in-sync replica, the default, and required for idempotence). [How acks works](https://monedula.dev/kafka-simulator/configs/acks/)
- [`min.insync.replicas`](https://kafka.apache.org/43/configuration/topic-configs/#topicconfigs_min.insync.replicas): The fewest in-sync replicas, leader included, that must have a write for an acks=all produce to succeed (default 1); with fewer in the ISR the leader rejects the write with NOT_ENOUGH_REPLICAS. [How min.insync.replicas works](https://monedula.dev/kafka-simulator/configs/min-insync-replicas/)

## Further reading

- [Apache Kafka documentation](https://kafka.apache.org/43/design/design/#replication)
