---
title: "Kafka isolation.level: read_committed vs read_uncommitted"
description: "One transaction commits across two partitions, a second aborts. Compare what Kafka read_committed and read_uncommitted consumers see at each step."
url: https://monedula.dev/kafka-simulator/scenarios/transactions-read-committed/
---

# Kafka isolation.level: read_committed vs read_uncommitted

Scenario 04.2.2 · Transactions & read_committed. Transactions · Advanced · about 3 min · Apache Kafka 4.3.

A transactional producer commits atomically across partitions; read_committed lags the LSO and skips an aborted batch.

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

## What you start with

A transactional producer commits atomically across two partitions, then runs a second transaction it aborts. Two consumer groups read the same topic - one read_committed, one read_uncommitted - so you can compare exactly what each isolation level sees.

## Step by step

1. **Cluster ready · two groups** (t+0.000s): orders has 2 partitions, RF=3, min.ISR=2. Group rc is read_committed, ru is read_uncommitted. A transactional producer tx1 is idle. Press ▶. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=04.2.2&t=0)
2. **begin transaction** (t+0.100s): tx1 opens a transaction (transactional.id tx-app-1). Nothing is written yet. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=04.2.2&t=1)
3. **Produced · uncommitted** (t+1.000s): tx1 wrote one record to each partition. Both records are replicated (HW advanced), so read_uncommitted (ru) sees them - but the LSO is frozen, so read_committed (rc) is stuck and sees nothing. Neither partition's record is visible to rc until the transaction commits. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=04.2.2&t=2)
4. **commit · LSO advances** (t+1.900s): commit_transaction advances the LSO to the high watermark on both partitions and rc sees the whole transaction. The simulator does both in one step; in Kafka the markers land on each partition separately, so a reader can briefly see one partition's records before the other's. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=04.2.2&t=3)
5. **Second txn · uncommitted** (t+2.900s): tx1 began a second transaction and wrote one more record to p0. ru briefly sees it; rc remains at the committed LSO. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=04.2.2&t=4)
6. **abort · range skipped** (t+3.600s): abort_transaction records the aborted range and jumps the LSO past it. read_committed skips the aborted record entirely - it is never delivered to rc, while ru already saw it. [Open at this step](https://monedula.dev/kafka-simulator/playground/?scenario=04.2.2&t=5)

## The takeaway

read_uncommitted sees records the moment they are written, while read_committed lags at the LSO and never delivers the aborted batch - isolation.level is what makes transactional output safe to consume.

## Configs in this scenario

- [`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/)
- [`transactional.id`](https://kafka.apache.org/43/configuration/producer-configs/#producerconfigs_transactional.id): A stable name that turns on transactions for a producer (and implies idempotence); a new producer that calls initTransactions() with the same id fences the older one.
- [`isolation.level`](https://kafka.apache.org/43/configuration/consumer-configs/#consumerconfigs_isolation.level): read_uncommitted (the default) returns every record, including those of open and aborted transactions; read_committed returns only committed transactional records and stops at the last stable offset. [How isolation.level works](https://monedula.dev/kafka-simulator/configs/isolation-level/)

## Further reading

- [Apache Kafka documentation](https://kafka.apache.org/43/configuration/consumer-configs/#consumerconfigs_isolation.level)
