Messaging Β· 02

Kafka Architecture

Kafka looks like a queue and behaves like a database log. This page builds the model from the ground up: why an append-only log is the primitive, how topics split into partitions and segments, how replication, the ISR and the high watermark make data durable, why ZooKeeper is gone, what makes it fast, how keys and retention shape your design, and how to size a cluster, ending with a session you can run locally in five minutes.

12
Chapters
4.0
Kafka version
KRaft
Metadata mode
1
Local lab
01
Chapter One - Why It Exists

The Commit Log as a Primitive

Kafka was built at LinkedIn to move activity data between systems, and its central decision was to make the append-only log the thing you talk to, instead of a queue that deletes messages as they are read. A log is simple: records are added at the end, each gets a sequential number (the offset), and nothing is modified. Reading is a separate concern. A reader remembers its own position, and many readers can sit at different positions in the same log.

A queue forgets, a log remembers
Queue: reading removes the message m4 m3 m2 consume m1 gone for everyone. A second consumer never sees m1. Log: reading only moves a bookmark (the offset) m0 0 m1 1 m2 2 m3 3 m4 4 m5 5 m6 6 m7 7 offset billing is at 5 new service replays from 2 Messages stay until retention expires. Each consumer group has its own offset. Replay = move the bookmark back.

That one difference explains most of Kafka's behaviour: replay (move the offset back), independent consumers (each group keeps its own offset), retention by time or size rather than by consumption, and very high throughput (sequential appends and sequential reads are the cheapest thing a disk does).

Traditional queue (RabbitMQ classic, SQS)Log (Kafka)
After a message is readDeleted (acked)Stays until retention removes it
Many independent consumers of one streamNeeds a copy of the message per consumer (fan-out exchange, SNS to SQS)Free: each consumer group tracks its own offset
Replay historyNot possible once ackedReset the offset to an earlier position or timestamp
Delivery trackingBroker tracks every message (ack, redelivery)Consumer tracks one number per partition
Per-message operationsAck, nack, delay, priority, TTL, requeueNone: you move the offset
Work distributionCompeting consumers on one queuePartitions assigned to the consumers of a group
Best atTask queues, routing, per-message controlEvent streams, high volume, replay, many consumers, stream processing
⚠ Using Kafka as a task queue
  • Kafka has no per-message acknowledgment, no delayed delivery, no priority and no "skip this one for now". A single slow message holds up every message behind it in its partition. If your workload is "run these jobs, retry the failed ones later", a queue (SQS, RabbitMQ) fits better. Choose Kafka when the stream of facts is the product.
Key insight: A queue is a to-do list: you cross items off. A log is a ledger: entries are never erased, and each reader keeps a finger on the page they have reached. Two accountants can read the same ledger at different pages without disturbing each other.
02
Chapter Two - The Log

Topics, Partitions, Offsets and Segments

A topic is a named stream. To scale it, a topic is split into partitions, and each partition is its own append-only log. Every record in a partition gets the next offset, a 64-bit sequence number that never changes and is never reused. A record is therefore addressed by topic + partition + offset.

One topic, three partitions, each an independent ordered log
topic: orders (3 partitions) partition 0 0 1 2 3 4 5 6 7 8 next write partition 1 0 1 2 3 4 5 6 next write partition 2 0 1 2 3 4 5 6 7 next write Offsets are per partition: partition 0 offset 5 and partition 1 offset 5 are different records. There is no global order across partitions.
TermMeaningWhy it matters
TopicA named category of records, e.g. ordersThe unit producers write to and consumers subscribe to
PartitionOne ordered log of a topic, stored as a directoryThe unit of ordering, parallelism and replication
OffsetPosition of a record inside its partitionWhat consumers commit to remember their progress
RecordKey (optional), value, headers, timestampKey decides the partition; timestamp drives retention and time-based lookup
SegmentA file chunk of a partition (roll at 1 GiB or by time)The unit of deletion: retention removes whole segments, never single records
What a partition looks like on disk

A partition is a directory of segment files. Only the newest segment (the active segment) is written to; older ones are immutable. This design is what makes retention cheap (delete a file) and lookups fast (binary-search a small index, then read forward).

Directory of one partition replica on a broker
orders-0/ <- one directory per partition replica on a broker 00000000000000000000.log <- segment: the records (named by its first offset) 00000000000000000000.index <- sparse map: offset -> byte position in the .log 00000000000000000000.timeindex <- sparse map: timestamp -> offset 00000000000000004711.log <- next segment starts at offset 4711 00000000000000004711.index 00000000000000004711.timeindex leader-epoch-checkpoint partition.metadata
  • A segment rolls when it reaches segment.bytes (default 1 GiB) or the age in segment.ms. The file name is the base offset, the offset of the first record inside it.
  • The .index is sparse: one entry per few KB of data. A lookup finds the nearest earlier entry and scans a short distance. The .timeindex does the same for timestamps, which is how "start from yesterday 09:00" works.
  • The log is only ever appended to, so writes are sequential. Old data is removed by deleting whole segment files.
Looking inside a segment
Shell - Kafka ships a tool that prints segment contents
$ bin/kafka-dump-log.sh --files /var/lib/kafka/data/orders-0/00000000000000000000.log --print-data-log Dumping /var/lib/kafka/data/orders-0/00000000000000000000.log Log starting offset: 0 baseOffset: 0 lastOffset: 0 count: 1 ... producerId: 4001 producerEpoch: 0 baseSequence: 0 ... compresscodec: none | offset: 0 CreateTime: 1761947012345 keySize: 4 valueSize: 31 sequence: 0 headerKeys: [] key: c-17 payload: {"orderId":"o-1","total":10}

The first line is a batch header: Kafka stores records in batches, and the producer id, epoch and sequence there are what make idempotent producers work (page 03). Output above is abridged and shows the shape, not exact values.

⚠ Assuming order across partitions
  • Offsets increase within a partition only. Two records with keys that hash to different partitions have no defined relative order, even if one was sent a millisecond before the other. Anything that needs "A before B" must share a key (page 01, ordering).
03
Chapter Three - The Cluster

Brokers, Leaders and Followers

A Kafka cluster is a set of brokers (servers). Each partition is stored on several brokers, controlled by the topic's replication factor. For each partition exactly one replica is the leader and the rest are followers.

Three brokers, topic orders with 3 partitions, replication factor 3
Broker 1 orders-0 LEADER orders-1 follower orders-2 follower Broker 2 orders-0 follower orders-1 LEADER orders-2 follower Broker 3 orders-0 follower orders-1 follower orders-2 LEADER Every partition has one leader. Producers and consumers talk only to the leader; followers copy from it. Leaders are spread so that no single broker carries all the traffic.
A producer sends a record for partition 1
β–Ά
It finds the leader of orders-1 from cluster metadata and writes only to that broker. Producers never write to followers
The leader appends to its log
β–Ά
Followers continuously fetch from the leader, the same way a consumer would, and append to their own copy
A consumer reads partition 1
β–Ά
It also reads from the leader by default. (Since Kafka 2.4, follower fetching lets a consumer read from a nearby replica to save cross-zone traffic, client.rack)
The leader's broker dies
β–Ά
A controller picks a new leader from the replicas that are in sync. Clients get a metadata error, refresh metadata and continue against the new leader
The old broker comes back
β–Ά
It rejoins as a follower, truncates anything beyond what the new leader has, and catches up. With auto.leader.rebalance.enable=true (default) leadership is later moved back to balance the load

One broker, the active controller, manages the cluster: it detects broker failures, elects partition leaders, and publishes the result as cluster metadata. How the controller is elected and where the metadata lives changed fundamentally in recent Kafka versions (chapter 05).

RoleCount per partitionServes reads/writesCan become leader
Leader1Yesn/a
Follower in the ISR (in sync)RF - 1 minus laggardsNo (follower fetch aside)Yes
Follower out of the ISR (lagging)variesNoNo (unless unclean election is enabled)
04
Chapter Four - Durability

Replication, the ISR and the High Watermark

Replication is where Kafka's guarantees come from, and the settings interact, so it pays to understand the moving parts before touching them.

Replication state of one partition: log end offset, ISR, high watermark
Leader (broker 1) 0 1 2 3 4 5 6 7 Follower A (broker 2) 0 1 2 3 4 5 6 Follower B (broker 3) 0 1 2 3 high watermark = 7 consumers can read offsets 0..6 ISR = {Leader, Follower A}. Follower B has fallen behind (offset 4) and was removed from the ISR.
TermMeaning
Replication factor (RF)Number of copies of each partition, including the leader. Set per topic. Production default: 3
ISR (in-sync replicas)The leader plus the followers that are caught up. A follower is dropped from the ISR if it has not caught up within replica.lag.time.max.ms (default 30 s) and re-added when it catches up
Log end offset (LEO)The next offset a replica will write
High watermark (HW)The highest offset replicated to all ISR members. Consumers can only read below the HW, so they never see data that could be lost by a leader failover
Leader epochA counter that increases at each leader change; followers use it to truncate divergent data safely after a failover
Three settings that decide whether you can lose data
SettingWhereDefault (4.0)Role
acksProducerall0: do not wait. 1: wait for the leader only. all: wait for every in-sync replica (at least min.insync.replicas)
min.insync.replicasTopic / broker1Minimum ISR size for an acks=all write to succeed. If the ISR is smaller, the write is rejected (NotEnoughReplicasException)
replication.factorTopicbroker default.replication.factor = 1Number of copies. The broker default of 1 is for development only

acks=all alone is not a guarantee. If the ISR has shrunk to only the leader and min.insync.replicas=1, acks=all means "the leader has it", which is the same as acks=1. The pair **RF=3, min.insync.replicas=2, acks=all** is the standard durable setting.

RFmin.insyncacksOne broker downTwo brokers down
32allWrites continue, no lossWrites rejected; reads continue; no loss
31allWrites continueWrites continue on the lone leader; if it then dies, acknowledged data is lost
321Writes continueAcknowledged after leader write only; lost if the leader dies before followers copy
11allPartition unavailableUnavailable; data lost if the disk is lost
⚠ Unclean leader election
  • If every in-sync replica is gone and only an out-of-sync follower remains, Kafka can either wait (partition unavailable) or elect the stale follower (available, but it is missing the newest records, which then disappear). unclean.leader.election.enable defaults to false: Kafka chooses consistency over availability. Enable it only for data you can afford to lose, such as metrics.
Durable producer checklist
  • Topic: replication.factor=3, min.insync.replicas=2.
  • Producer: acks=all and enable.idempotence=true (both are the default since Kafka 3.0, but state them explicitly so a reader and a code review can see the intent).
  • Spread the replicas across availability zones (broker.rack) so a zone failure leaves at least two in sync.
05
Chapter Five - Metadata

ZooKeeper to KRaft

For its first decade Kafka stored cluster metadata (topics, partitions, leaders, configs, ACLs) in Apache ZooKeeper. That meant running and operating a second distributed system, and the controller had to reload all metadata from ZooKeeper after a failover, which limited cluster size and recovery time. KRaft (Kafka Raft) removes the dependency: a set of controller nodes run the Raft consensus protocol and keep the metadata in an internal, replicated Kafka log named __cluster_metadata. Brokers are consumers of that log.

Where cluster metadata lives: ZooKeeper era vs KRaft
Before: Kafka + a separate ZooKeeper ensemble (removed in Kafka 4.0) ZooKeeper ensemble (3 or 5 nodes) Broker 1 Broker 2 Broker 3 metadata Two systems to deploy, secure, monitor and upgrade. Controller state is reloaded from ZooKeeper after a failover. Now: KRaft, controllers run Raft and store metadata in a Kafka log Controller quorum (3 nodes, Raft) log: __cluster_metadata Broker 1 Broker 2 Broker 3 metadata log
Date / versionEvent
Kafka 2.8 (2021)KRaft available as early access
Kafka 3.3 (2022)KRaft declared production-ready for new clusters
Kafka 3.9The last release that supports ZooKeeper; the bridge for migrating existing clusters
Kafka 4.0 (March 2025)ZooKeeper removed. KRaft is the only mode. Existing ZooKeeper clusters must first be migrated to KRaft, via 3.9, before upgrading to 4.x
Configuring a node
server.properties - a combined broker+controller node for development
# A node can be a broker, a controller, or both. Production: dedicated controllers. process.roles=broker,controller node.id=1 controller.quorum.voters=1@localhost:9093 listeners=PLAINTEXT://:9092,CONTROLLER://:9093 controller.listener.names=CONTROLLER advertised.listeners=PLAINTEXT://localhost:9092 log.dirs=/var/lib/kafka/data
  • process.roles is broker, controller or both. Small clusters and local setups combine them; production clusters usually run 3 dedicated controller nodes so a broker overload cannot destabilise metadata.
  • The controller quorum needs a majority: 3 controllers tolerate 1 failure, 5 tolerate 2. An even number adds cost without adding tolerance.
  • Kafka 4.x also supports dynamic controller quorums (controller.quorum.bootstrap.servers) so controllers can be added or removed without a restart; the static controller.quorum.voters form above remains valid.
  • Storage must be formatted with a cluster id before first start (kafka-storage.sh format). The official Docker image does this for you.
What this means for you
  • If you read an older tutorial that starts ZooKeeper, ignore that part: the zookeeper.connect property and zookeeper-server-start.sh no longer exist in 4.x.
  • Clients are unaffected. bootstrap.servers still points at brokers; applications never talked to ZooKeeper.
  • Kafka 4.0 brokers and tools need Java 17; the Java clients run on Java 11 or later.
06
Chapter Six - Performance

Why Kafka Is Fast

Kafka routinely handles hundreds of thousands of records per second per broker on ordinary hardware, with durable storage on disk. There is no trick; it follows the grain of the machine in five ways.

TechniqueWhat happensEffect
Sequential I/OAppends to the end of a file; reads scan forwardDisks, and SSDs even more so, are far faster at sequential than random access
OS page cacheKafka does not keep its own cache; recent segments live in the operating system's page cacheA consumer that keeps up reads from RAM. No JVM heap, no garbage collection for cached data, and the cache survives a broker restart
Zero-copy transferFor plaintext connections the broker uses sendfile: data goes from page cache to the network card without copying through the JVMFar less CPU and memory bandwidth. Not available with TLS, which must encrypt in user space
BatchingProducers group records per partition (batch.size, linger.ms); the broker stores and ships whole batchesAmortises network and disk overhead across many records
CompressionA whole batch is compressed once by the producer and stays compressed on disk and on the wire (compression.type: gzip, snappy, lz4, zstd)Less network and disk; consumers decompress
Partitioned parallelismPartitions spread across brokers and consumersThroughput scales by adding partitions and machines
Producer settingDefault (4.0)Effect of raising it
linger.ms5Wait longer to fill batches: more throughput and compression, more latency. (Was 0 before 4.0)
batch.size16384 (16 KiB)Larger batches per partition: better throughput, more memory
compression.typenonelz4 or zstd usually pay off for JSON/text
buffer.memory33554432 (32 MiB)More room when the broker is slow before send() blocks (max.block.ms, default 60 s)
⚠ "Kafka is fast, so I will send one record at a time and flush"
  • Calling flush() after every send() defeats batching: each record becomes its own request, and throughput can drop by an order of magnitude. Let the producer batch, and use callbacks or the Future only to detect failures.
07
Chapter Seven - Partitioning

Keys, the Partitioner and Skew

The partition a record lands in decides its ordering group, its consumer, and the load on the broker. The producer's partitioner chooses it:

CaseDefault behaviourConsequence
Record has a keytoPositive(murmur2(keyBytes)) % numPartitionsSame key always goes to the same partition (as long as the partition count does not change)
Record has no keyThe producer fills a batch for one partition, then moves to another (sticky, load-aware since Kafka 3.3)Even spread, no ordering guarantee between records
Explicit partition numberUsed as givenFull control; you own the balance
Choosing the key
  • Use the entity whose order matters: customerId, accountId, orderId. All events of that entity then stay ordered.
  • Pick a key with many distinct values and an even spread. A key like country with 80% of traffic from one value sends 80% of the load to one partition: a hot partition, one overloaded broker and one lagging consumer while the others idle.
  • If one key is genuinely hot, salt it (tenantId + "-" + (n % 8)) and accept that order now holds only per salted key.
Java - which partition does a key land on? (kafka-clients on the classpath)
byte[] keyBytes = "c-17".getBytes(StandardCharsets.UTF_8); int numPartitions = 3; int partition = Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions; // org.apache.kafka.common.utils.Utils - the same code the default partitioner uses
⚠ Increasing the partition count on a live keyed topic
  • You can add partitions, never remove them. But the formula uses numPartitions, so after growing from 3 to 6 the key c-17 can map to a different partition. New events of c-17 then go to a partition that does not contain its history, and per-key ordering is broken across the change. Consumers that keep per-key state also break.
  • Plan the partition count up front with headroom. If you must grow a keyed topic, create a new topic with the new count and migrate.
08
Chapter Eight - Retention

Delete vs Compact

Kafka keeps data according to the topic's cleanup.policy, which can be delete, compact, or both.

PolicyRuleUse forKey defaults (4.0)
deleteRemove whole segments older than retention.ms or when the partition exceeds retention.bytesEvent streams: orders, clicks, logsretention.ms = 7 days (log.retention.hours=168), retention.bytes = -1 (unlimited), checked every 5 min
compactKeep at least the latest record for each key; older records with the same key are removed in the backgroundState: latest customer profile, config, changelog topics, consumer offsets (__consumer_offsets)min.cleanable.dirty.ratio = 0.5, min.compaction.lag.ms = 0, delete.retention.ms = 1 day
compact,deleteCompact, and also drop everything older than the retention timeBounded state historyBoth sets above
Log compaction: keep the latest value for each key
Before compaction k1=v1 off 0 k2=v1 off 1 k1=v2 off 2 k3=v1 off 3 k2=v2 off 4 k1=v3 off 5 k3=null off 6 After compaction (offsets are kept, superseded records disappear) k2=v2 off 4 k1=v3 off 5 k3=null off 6 k3=null is a tombstone: it is kept for delete.retention.ms (default 1 day) so consumers see the delete, then removed.
  • Retention deletes a segment only when all records in it are old enough, and never touches the active segment. A quiet topic can therefore keep data longer than retention.ms. Lower segment.ms if that matters.
  • Compaction never changes offsets and does not reorder: it only removes superseded records. A consumer reading a compacted topic from the start sees the latest value for every key, plus some older ones that have not been cleaned yet.
  • A record with a key and a null value is a tombstone: it marks the key as deleted. It is retained for delete.retention.ms so slow consumers can observe the delete, then removed.
  • Compaction requires keys: producing a record without a key to a compacted topic is rejected.
⚠ Treating compaction as immediate
  • Compaction runs in the background on closed segments once the dirty ratio is high enough. A compacted topic will still contain old duplicates for a while, so consumers must still handle several values per key and apply them in order. Do not use compaction as a substitute for a database query.
09
Chapter Nine - Sizing

How Many Partitions? How Much Disk?

Partition count is the hardest setting to change later, so size it from numbers. Use measured throughput from your own producers and consumers; the figures below are examples of the method, not benchmarks.

Partitions: take the larger of two ceilings
QuantityExample valueNotes
Target throughput for the topic (T)100 MB/sPeak, with growth headroom
Measured producer throughput per partition (P)10 MB/sTest with real record size and compression
Measured consumer throughput per partition (C)5 MB/sOften the slower side: includes your processing time and DB writes
Partitions neededmax(T/P, T/C) = max(10, 20) = 20Consumers are the bottleneck, so size for them
HeadroomRound up to 24 or 30A number with many divisors lets you run 2, 3, 4, 6... consumers evenly

The partition count is also the ceiling on consumer parallelism in one group: 24 partitions means at most 24 active consumers. More consumers than partitions sit idle.

Costs of too many partitions
  • More open file handles and memory per broker (each partition has segment files and indexes).
  • Longer recovery: after a broker failure, every partition it led needs a new leader election.
  • More replication traffic and end-to-end latency, since each partition replicates independently.
  • Each consumer has more partitions to track and each rebalance moves more state.
  • KRaft raised the practical ceiling a lot compared with ZooKeeper, but "as many as possible" is still the wrong default.
Disk: retention times throughput times replication
ItemValue
Ingest20 MB/s average
Retention7 days = 604,800 s
Raw data20 x 604,800 = 12.1 TB
With replication factor 336.3 TB across the cluster
With 2:1 compression on diskAbout 18 TB
Operating headroomPlan for no more than about 60 to 70% full, so brokers can recover and rebalance: roughly 26 to 30 TB provisioned
Production topic defaults to put in your platform checklist
  • replication.factor=3, min.insync.replicas=2.
  • Set auto.create.topics.enable=false on brokers (default is true, and a typo in a topic name silently creates a new one with default settings: 1 partition, RF 1).
  • Create topics through code or tooling (Terraform, kafka-topics.sh, Spring NewTopic beans) so partition count, RF and retention are reviewed, not accidental.
10
Chapter Ten - Hands-On

Run a Broker and Look Inside

Nothing makes the previous chapters stick like watching them happen. This needs only Docker. The official image runs a single combined broker+controller in KRaft mode.

Start a broker and create a topic
Shell
$ docker run -d --name kafka -p 9092:9092 apache/kafka:4.0.0 $ docker exec kafka /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 \ --create --topic orders --partitions 3 --replication-factor 1 Created topic orders. $ docker exec kafka /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic orders Topic: orders PartitionCount: 3 ReplicationFactor: 1 Configs: segment.bytes=1073741824 Topic: orders Partition: 0 Leader: 1 Replicas: 1 Isr: 1 Topic: orders Partition: 1 Leader: 1 Replicas: 1 Isr: 1 Topic: orders Partition: 2 Leader: 1 Replicas: 1 Isr: 1

Output is abridged; your build may print extra columns such as the topic id. With one broker, replication factor can only be 1. On a real cluster you would see different leaders and a longer ISR list.

Produce keyed records and see them land in partitions
Shell - same key, same partition
$ docker exec -it kafka /opt/kafka/bin/kafka-console-producer.sh --bootstrap-server localhost:9092 \ --topic orders --property parse.key=true --property key.separator=: >c-17:order 1 >c-42:order 2 >c-17:order 3 $ docker exec kafka /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 \ --topic orders --from-beginning --property print.key=true --property print.partition=true Partition:2 c-17 order 1 Partition:2 c-17 order 3 Partition:0 c-42 order 2

Both c-17 records share a partition, so they stay in order. The partition numbers you see depend on the hash, but the grouping is always the same. The console consumer prints partitions in whatever order it fetched them, which is also a live demonstration that there is no order across partitions.

Inspect progress and the files on disk
Shell
$ docker exec kafka /opt/kafka/bin/kafka-get-offsets.sh --bootstrap-server localhost:9092 --topic orders orders:0:1 orders:1:0 orders:2:2 $ docker exec kafka ls /tmp/kraft-combined-logs | head __cluster_metadata-0 __consumer_offsets-0 orders-0 orders-1 orders-2

The three numbers are the log end offset of each partition (1, 0 and 2 records). __cluster_metadata-0 is the KRaft metadata log from chapter 05, and __consumer_offsets-* is where consumer groups commit their positions. The log directory path comes from the image's default configuration and may differ between image versions.

Clean up
  • docker rm -f kafka removes the container and its data.
11
Chapter Eleven - Interview

Questions You Should Be Able to Answer

Crisp answers for the questions that come up in interviews on this topic.

  • Q: How is Kafka different from a message queue?
    Kafka is a distributed, partitioned, replicated log. Records are retained for a period regardless of consumption, consumers track their own offsets, and many consumer groups can read the same data independently and replay it. A queue deletes a message once acknowledged and tracks delivery per message.
  • Q: What is a partition and why does Kafka have them?
    A partition is one ordered append-only log of a topic. Partitions give parallelism (one consumer per partition within a group), scalability (spread across brokers) and the unit of ordering (order is guaranteed only within a partition).
  • Q: What is an offset?
    A sequential, immutable position of a record within one partition. A consumer commits the next offset it wants to read, so after a restart it resumes where it left off.
  • Q: How does Kafka guarantee ordering?
    Only within a partition. Records with the same key hash to the same partition, so they stay in order for a single consumer of that partition. There is no ordering across partitions.
  • Q: Explain leader, follower, ISR and the high watermark.
    Each partition has one leader that serves all reads and writes; followers replicate from it. The ISR is the set of replicas caught up within replica.lag.time.max.ms. The high watermark is the highest offset replicated to all ISR members; consumers read only below it.
  • Q: How do you configure Kafka so that you never lose acknowledged data?
    Replication factor 3, min.insync.replicas=2, producer acks=all with idempotence enabled, unclean.leader.election.enable=false, and replicas across racks or zones. This tolerates one broker failure without loss and refuses writes rather than risk loss when two are down.
  • Q: What does acks=all mean if min.insync.replicas=1?
    The leader alone can satisfy it when the ISR has shrunk to one member, so it is effectively acks=1. acks=all is only as strong as min.insync.replicas.
  • Q: What changed in Kafka 4.0?
    ZooKeeper support was removed; KRaft is the only metadata mode. Controllers run Raft and store metadata in the __cluster_metadata log. The new consumer group protocol (KIP-848) became generally available, and linger.ms default became 5 ms. Brokers need Java 17.
  • Q: Why is Kafka fast?
    Sequential disk I/O, reliance on the OS page cache, zero-copy sendfile for plaintext, batching and compression of whole record batches, and horizontal scaling through partitions.
  • Q: Delete vs compact cleanup?
    delete removes whole old segments by age or size. compact keeps the latest record per key and removes older ones in the background; tombstones (null values) mark deletions. Compacted topics still contain old duplicates for some time.
  • Q: Why is changing the partition count of a keyed topic risky?
    The key-to-partition mapping depends on the partition count, so existing keys can move to different partitions, breaking per-key ordering and any consumer state keyed by partition assignment. Partitions can be added but never removed.
  • Q: How many partitions should a topic have?
    Divide target throughput by the measured per-partition throughput of the slower side (usually the consumer), add headroom, and remember it caps consumer parallelism. Too many partitions cost memory, file handles, recovery time and replication overhead.
12
Chapter Twelve - Summary

Cheat Sheet and Recap

Cheat sheet
ConceptRememberDefault / value (Kafka 4.0)
Record addressTopic + partition + offsetOffsets are per partition
OrderingOnly inside one partitionKey decides the partition
Segment sizeRetention deletes whole segmentssegment.bytes = 1 GiB
RetentionTime or size, not consumption7 days; retention.bytes unlimited
Durable writeRF 3 + min ISR 2 + acks=allacks=all and idempotence are on by default
min.insync.replicasFloor for the ISR on acks=all writes1 (raise to 2)
Unclean electionAvailability over consistency if enabledfalse
Replica lag limitLeaves the ISR after thisreplica.lag.time.max.ms = 30 s
MetadataKRaft only, no ZooKeeperRemoved in 4.0
CompactionLatest value per key, tombstone = deletedelete.retention.ms = 1 day
Partition countCan grow, never shrink; breaks key mappingBroker default num.partitions = 1
βˆ‘ Kafka architecture - what to remember
  • Kafka is a log, not a queue. Reading moves an offset; it does not delete.
  • The partition is everything: the unit of order, parallelism, replication and deletion.
  • One leader per partition; followers copy. The ISR and the high watermark decide what is safe to read and to acknowledge.
  • **Durability = RF 3 + min.insync.replicas=2 + acks=all**, not any one setting alone.
  • KRaft replaced ZooKeeper, and ZooKeeper is gone as of 4.0.
  • Choose keys for even spread and entity ordering; never grow a keyed topic casually.
  • Size from measurements: partitions = max over producer and consumer ceilings, disk = rate x retention x RF, with headroom.
Version note

Defaults and version facts on this page were checked against the Apache Kafka 4.0 configuration reference and release announcement on 2026-10-31. Kafka releases move on; re-check a value in the docs for your version before relying on it in production.

Next in this section