Kafka Interview Questions and Answers (2026): Kafka 4, KRaft and Exactly-Once
50+ Kafka interview questions with direct answers: partitions, acks and ISR, KRaft vs ZooKeeper, exactly-once, KIP-848 rebalancing, share groups and Spring Kafka.
New24 min read

These Kafka interview questions cover what interviewers ask Java and Spring Boot developers in 2026: partitions and consumer groups, replication and acks, KRaft instead of ZooKeeper, exactly-once delivery, Spring Kafka error handling, and the newer features that show you are current, such as the KIP-848 rebalance protocol and share groups (Kafka queues).
The guide is for freshers who have used Kafka in one project and for developers with 2 to 8 years of experience who need to explain trade-offs, not only definitions. Each answer starts with a short direct reply you can say out loud, then adds the detail and the follow-up the interviewer is likely to ask next. Everything is checked against Apache Kafka 4.x (4.4 is the newest release as of October 2026) and Spring for Apache Kafka 4.x.
If you want practice on production problems (duplicates, lag, data loss), read this page first and then move on to the companion post with scenario questions.
In this guide
- Kafka basics: topics, partitions, offsets and consumer groups
- Architecture: brokers, replication and KRaft vs ZooKeeper
- Producer interview questions: acks, idempotence and partitioning
- Consumer interview questions: offsets, commits and rebalancing
- Delivery guarantees and Kafka exactly-once
- Share groups: queues for Kafka
- Operations questions for experienced developers
- Kafka interview questions for Spring Boot
- Comparisons: Kafka vs RabbitMQ and friends
- FAQ
Kafka basics: topics, partitions, offsets and consumer groups
What is Apache Kafka?
Apache Kafka is a distributed, replicated commit log used for event streaming. Producers append records to topics, Kafka stores them durably on disk for a configured retention period, and any number of consumers read them at their own pace. It is used for event-driven microservices, data pipelines, change data capture and stream processing.
The important word is log. Reading a record does not delete it. That is the main difference from a traditional queue, and it is what makes replay, multiple independent readers and high throughput possible.
What are topics, partitions and offsets?
A topic is a named stream of records, such as orders. Each topic is split into partitions, and each partition is an ordered, append-only log stored on a broker. Every record in a partition gets a sequential number called the offset. A record is identified by topic, partition and offset.
Partitions are the unit of parallelism and ordering. More partitions let more consumers work in parallel. Ordering is only guaranteed inside one partition, never across a whole topic.
What is a broker and what is a Kafka cluster?
A broker is one Kafka server process that stores partitions and serves reads and writes. A cluster is a group of brokers that share the partitions of all topics between them. In Kafka 4.x every cluster also runs KRaft controllers, which manage metadata such as which broker leads which partition.
What is a consumer group?
A consumer group is a set of consumers that share the work of reading a topic. Kafka assigns each partition to exactly one consumer in the group, so every record is processed once per group. Different groups read the same topic independently, each with its own offsets.
That gives you both patterns from one topic: inside a group it behaves like a work queue; across groups it behaves like publish-subscribe. A billing service and an analytics service can each have their own group on orders and never affect each other.
What happens if a group has more consumers than partitions?
The extra consumers sit idle. With 6 partitions, a seventh consumer in the same group gets no partition. This is why the partition count sets the ceiling for consumer parallelism in a classic consumer group. Share groups, covered below, remove that ceiling for queue-style work.
What is the role of a message key?
The key decides the partition. Records with the same key go to the same partition (as long as the partition count does not change), so they are stored and consumed in order. A typical key is an entity id such as orderId or customerId.
Records with a null key are spread across partitions by the producer's sticky partitioning: it fills a batch for one partition and then moves on, which gives good batching without per-record round-robin.
How long does Kafka keep messages?
Until the retention limit is reached, whether or not anyone has read them. The defaults are time based (log.retention.hours=168, seven days) and can also be size based with retention.bytes. Retention deletes whole closed log segments, not single records.
What is log compaction?
Log compaction (cleanup.policy=compact) keeps at least the latest record for each key and removes older ones in the background. A record with a null value, called a tombstone, marks a key for deletion. Compacted topics work like a changelog or a durable key-value snapshot; Kafka itself uses one for __consumer_offsets.
What the interviewer is checking: whether you understand that Kafka is a log, not a queue. Mention that ordering is per partition and that keys control placement, and you have answered half of the follow-ups before they are asked.
Architecture: brokers, replication and KRaft vs ZooKeeper
What is KRaft and why did Kafka remove ZooKeeper?
KRaft is Kafka's built-in consensus layer, based on the Raft protocol. A small quorum of controller nodes stores cluster metadata in an internal, replicated log (__cluster_metadata), and brokers follow that log. Kafka 4.0 (March 2025) is the first major release that runs entirely without ZooKeeper; ZooKeeper mode is gone.
The reasons: one system to deploy and secure instead of two, faster controller failover because the new controller already has the metadata in memory, and much better scaling in the number of partitions a cluster can hold. Clusters still on ZooKeeper must migrate to KRaft on a 3.x bridge release (3.9 is the last) before upgrading to 4.x.
KRaft vs ZooKeeper: what are the practical differences?
- Metadata storage: ZooKeeper kept it in znodes in a separate ensemble; KRaft keeps it in a Kafka log replicated by the controller quorum.
- Controller: with ZooKeeper one broker was elected controller and had to load all state on failover; with KRaft one controller is active and the others are hot standbys.
- Operations: one product, one security model, one set of configs (
process.roles,controller.quorum.bootstrap.servers). - Quorum changes: since Kafka 3.9 (KIP-853) controllers can be added or removed dynamically.
How does replication work in Kafka?
Each partition has a replication factor, usually 3. One replica is the leader and handles all writes (and, by default, reads). The other replicas are followers that fetch from the leader and copy its log. If the leader's broker fails, the controller elects a new leader from the in-sync followers.
What is the ISR (in-sync replica set)?
The ISR is the set of replicas that are fully caught up with the leader, including the leader itself. A follower that falls behind for longer than replica.lag.time.max.ms is removed from the ISR, and added back once it catches up. Only ISR members are normally eligible to become leader, which is what protects acknowledged writes.
What does min.insync.replicas do?
It sets how many replicas must be in sync for a write with acks=all to succeed. With replication factor 3 and min.insync.replicas=2, the partition keeps accepting writes with one broker down; if the ISR drops to one, producers get NotEnoughReplicasException instead of a write that only one disk holds. The broker default is 1, so set it per topic or cluster for important data.
What is unclean leader election?
It allows a replica that is not in the ISR to become leader when no in-sync replica is available. The partition comes back online faster, but records the old leader had acknowledged and the new one never received are lost. It is disabled by default (unclean.leader.election.enable=false), and for business data it should stay that way. Kafka 4.1 also enabled Eligible Leader Replicas (KIP-966) by default on new clusters: the controller tracks replicas that left the ISR but are known to hold every committed record, so they can still be elected without data loss.
What is tiered storage?
Tiered storage (KIP-405) lets brokers move older log segments to a remote store such as object storage while keeping recent data on local disk. Consumers read old data transparently. It became production-ready in Kafka 3.9 and makes long retention much cheaper, because broker disks only need to hold the hot tail of each partition.
Producer interview questions: acks, idempotence and partitioning
How does a Kafka producer send a message?
The producer serializes the key and value, picks a partition, and adds the record to an in-memory batch for that partition. A background sender thread ships batches to partition leaders when a batch is full (batch.size, 16 KB by default) or when linger.ms expires. Kafka 4.0 changed the linger.ms default from 0 to 5 ms, which gives better batching at a tiny latency cost.
send() is asynchronous and returns a Future<RecordMetadata>. Use the callback to log failures; calling get() on every send turns the producer into a slow, one-at-a-time client.
What is the difference between acks=0, acks=1 and acks=all?
acks controls when the leader answers the producer. With acks=0 the producer does not wait at all. With acks=1 the leader answers after writing to its own log. With acks=all (or -1) it answers only after every in-sync replica has the record. acks=all has been the default since Kafka 3.0.
- acks=0: lowest latency; any failure loses data; fine for metrics you can drop.
- acks=1: loses data if the leader dies before followers copy the record.
- acks=all: no loss of acknowledged writes while one in-sync replica survives; pair it with
min.insync.replicas=2.
What is an idempotent producer?
An idempotent producer guarantees that retries do not create duplicates or reorder records within a partition. The broker gives each producer an id and tracks a sequence number per partition; if a retried batch arrives with a sequence it has already written, the broker discards it. enable.idempotence=true is the default since Kafka 3.0, as long as no conflicting setting is present.
It requires acks=all, retries greater than 0, and max.in.flight.requests.per.connection of 5 or less. If you explicitly enable idempotence and also set a conflicting value, the producer fails with a ConfigException; if you did not set it explicitly, idempotence is quietly turned off. That silent case is a classic source of duplicates.
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
// These are already the defaults since Kafka 3.0; stating them protects you from a stray override.
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
props.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 120_000);
try (var producer = new KafkaProducer<String, String>(props)) {
producer.send(new ProducerRecord<>("orders", "order-1001", "{\"status\":\"PLACED\"}"),
(metadata, ex) -> {
if (ex != null) log.error("send failed", ex);
});
}How does Kafka choose the partition for a record?
If the record names a partition, that one is used. Otherwise, with a key, the default partitioner computes a murmur2 hash of the serialized key bytes and takes it modulo the number of partitions. With no key, it uses sticky partitioning. The program below reproduces the keyed formula; we checked it against kafka-clients 4.2.1 and it matched on 60,000 keys.
import java.nio.charset.StandardCharsets;
import java.util.List;
public class PartitionForKey {
// Same algorithm as Kafka's Utils.murmur2 (used by the default partitioner for keyed records)
static int murmur2(byte[] data) {
int length = data.length;
int m = 0x5bd1e995;
int h = 0x9747b28c ^ length;
for (int i = 0; i < length / 4; i++) {
int i4 = i * 4;
int k = (data[i4] & 0xff) + ((data[i4 + 1] & 0xff) << 8)
+ ((data[i4 + 2] & 0xff) << 16) + ((data[i4 + 3] & 0xff) << 24);
k *= m;
k ^= k >>> 24;
k *= m;
h *= m;
h ^= k;
}
int tail = length & ~3;
switch (length % 4) {
case 3: h ^= (data[tail + 2] & 0xff) << 16;
case 2: h ^= (data[tail + 1] & 0xff) << 8;
case 1: h ^= data[tail] & 0xff;
h *= m;
}
h ^= h >>> 13;
h *= m;
h ^= h >>> 15;
return h;
}
static int partitionFor(String key, int partitions) {
byte[] bytes = key.getBytes(StandardCharsets.UTF_8); // what StringSerializer sends
return (murmur2(bytes) & 0x7fffffff) % partitions;
}
public static void main(String[] args) {
List<String> keys = List.of("order-1001", "order-1002", "order-1003", "order-1001", "customer-42");
for (String key : keys) {
System.out.printf("%-12s -> partition %d of 6%n", key, partitionFor(key, 6));
}
}
}Output on JDK 25:
order-1001 -> partition 0 of 6
order-1002 -> partition 0 of 6
order-1003 -> partition 4 of 6
order-1001 -> partition 0 of 6
customer-42 -> partition 3 of 6Two points to say in an interview: the same key always lands on the same partition (order-1001 twice), and different keys can share a partition (order-1001 and order-1002). The mapping depends on the partition count, so adding partitions moves keys and breaks per-key ordering for in-flight data.
Does Kafka guarantee message ordering?
Only within a partition. Records in one partition are stored and delivered in the order they were written. With the idempotent producer, retries cannot reorder them even with up to 5 in-flight requests. Across partitions there is no ordering, so if order matters for an entity, give all its events the same key.
What do retries and delivery.timeout.ms control?
retries defaults to Integer.MAX_VALUE, so in practice the limit is time: delivery.timeout.ms (two minutes by default) caps the total time from send() to success or failure, including batching, waiting and retries. When it expires, the callback gets an exception and the application must decide what to do. Tune the timeout instead of the retry count.
Why use compression and which codec?
Compression is applied per batch, so it works best with batching. It cuts network and disk use, often by a large factor for JSON. compression.type accepts gzip, snappy, lz4 and zstd; lz4 and zstd are common choices for a good balance of CPU and ratio. The default is none.
Consumer interview questions: offsets, commits and rebalancing
How does a Kafka consumer read messages?
A consumer subscribes to topics and calls poll() in a loop. Each call returns a batch of records (up to max.poll.records, 500 by default) from the partitions assigned to it. The consumer tracks its position per partition and periodically commits offsets so that, after a restart or rebalance, the group knows where to resume.
Where are consumer offsets stored?
In the internal compacted topic __consumer_offsets, managed by the group coordinator broker. The committed offset is the offset of the next record to read, so after processing offset 41 you commit 42. An application can also keep offsets in its own database and seek() to them on startup, which is useful when the offset must change in the same transaction as the data.
Auto commit vs manual commit: which should you use?
Auto commit (enable.auto.commit=true, the default, every 5 seconds) commits the positions returned by previous polls in the background. If you process records inside the poll loop, it is at-least-once and a crash repeats up to one interval of records. If you hand records to another thread, auto commit can mark them done before they are processed, and a crash loses them. Manual commit after processing makes the behavior explicit and easy to reason about.
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
try (var consumer = new KafkaConsumer<String, String>(props)) {
consumer.subscribe(List.of("orders"));
while (running) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(500));
for (ConsumerRecord<String, String> record : records) {
handle(record); // must be idempotent: it can run twice
}
if (!records.isEmpty()) {
consumer.commitSync(); // commit after the whole batch succeeded
}
}
}What does auto.offset.reset do?
It decides where a consumer starts when its group has no committed offset for a partition, or the committed offset no longer exists because retention deleted it. latest (the default) starts at the end and skips existing data; earliest starts from the oldest retained record; none throws an exception. Kafka 4 also accepts by_duration:<ISO-8601 duration>, for example by_duration:PT1H to start one hour back. A new group with latest that "sees nothing" is a very common interview story.
What is a rebalance and what triggers one?
A rebalance redistributes partitions among the members of a group. It is triggered when a consumer joins or leaves, when a consumer is considered dead (no heartbeat within the session timeout, or no poll() within max.poll.interval.ms, five minutes by default), or when the subscribed topics or their partition counts change.
In the classic protocol with the eager strategy, every consumer gives up all its partitions during a rebalance, so the whole group pauses. The cooperative sticky assignor reduced that by moving only the partitions that need to move.
What is the new consumer rebalance protocol (KIP-848)?
KIP-848 moves partition assignment from the clients to the broker-side group coordinator and makes rebalances fully incremental. There is no group-wide synchronization barrier: each consumer heartbeats, the coordinator computes a target assignment, and members converge to it one partition at a time while the rest keep consuming. It is generally available since Kafka 4.0.
It is enabled on brokers by default but opt-in on clients: set group.protocol=consumer (the default is still classic). With it, the client-side settings session.timeout.ms, heartbeat.interval.ms and partition.assignment.strategy no longer apply; the broker controls timeouts through group.consumer.session.timeout.ms and group.consumer.heartbeat.interval.ms, and assignors are server-side (uniform by default, or range, chosen with group.remote.assignor). The official consumer rebalance protocol page covers online migration from classic groups.
spring:
kafka:
consumer:
group-id: billing
properties:
group.protocol: consumerWhat is static group membership?
Static membership gives each consumer a stable group.instance.id. When that instance restarts within the session timeout, it gets the same partitions back without triggering a rebalance. It is useful for rolling deployments on Kubernetes, where pods restart one by one and you do not want a rebalance for each.
What is consumer lag?
Lag is the difference between the log-end offset of a partition and the group's committed offset: how many records are waiting. Rising lag means consumers cannot keep up. Check it with kafka-consumer-groups.sh --describe --group <group> or the consumer's records-lag-max metric, and alert on how long it stays high, not on one spike.
What the interviewer is checking: that you know when offsets are committed relative to processing, and what a rebalance does to a group. Mentioning KIP-848 and
group.protocol=consumersignals that your knowledge is from Kafka 4, not from a 2019 tutorial.
Delivery guarantees and Kafka exactly-once
What are at-most-once, at-least-once and exactly-once?
They describe what happens to a record when something fails. At-most-once may lose records but never repeats them. At-least-once never loses records but may repeat them. Exactly-once means each record's effect happens once. In Kafka, the difference comes down to when the consumer commits relative to processing, and whether transactions are used.
How does Kafka exactly-once work?
Kafka exactly-once combines the idempotent producer with transactions. A transactional producer (it has a transactional.id) writes output records to several partitions and commits the consumer's offsets in the same atomic transaction. Consumers reading with isolation.level=read_committed only see records from committed transactions. Kafka Streams turns all of this on with processing.guarantee=exactly_once_v2.
producer.initTransactions();
while (running) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(500));
if (records.isEmpty()) continue;
producer.beginTransaction();
try {
Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
for (ConsumerRecord<String, String> r : records) {
producer.send(new ProducerRecord<>("payments.validated", r.key(), validate(r.value())));
offsets.put(new TopicPartition(r.topic(), r.partition()), new OffsetAndMetadata(r.offset() + 1));
}
producer.sendOffsetsToTransaction(offsets, consumer.groupMetadata());
producer.commitTransaction();
} catch (ProducerFencedException e) {
throw e; // another instance took over this transactional.id
} catch (KafkaException e) {
producer.abortTransaction(); // then seek back to the last committed offsets and retry
}
}Is exactly-once possible when the consumer writes to a database?
Not with Kafka transactions alone. They are atomic only over Kafka partitions; a database write is outside the transaction. For Kafka-to-database flows, use at-least-once delivery with an idempotent consumer: store a processed event id with a unique constraint, or use an upsert, in the same database transaction as the business change. Alternatively, store the offsets in the database in that same transaction and seek to them on startup.
What is isolation.level?
A consumer setting with two values. read_uncommitted (the default) returns all records, including those from open or aborted transactions. read_committed returns only committed transactional records and non-transactional ones, and stops at the last stable offset of each partition. Exactly-once pipelines need read_committed downstream.
How do you make sure a Kafka message is never lost?
- Producer:
acks=all, idempotence on, and handle the send callback error instead of ignoring it. - Topic: replication factor 3 and
min.insync.replicas=2; keep unclean leader election off. - Consumer: commit offsets only after processing succeeds; never process asynchronously and commit first.
- Operations: retention long enough for the longest outage you plan for, and monitoring on under-replicated partitions.
Share groups: queues for Kafka
What are Kafka share groups (queues for Kafka)?
Share groups (KIP-932) are a second way to consume a topic, built for work-queue use cases. Instead of assigning each partition to one consumer, a share group lets many consumers read from the same partitions at once. Records are acquired with a time-limited lock (30 seconds by default) and acknowledged one by one as accept, release (retry) or reject; since 4.2 a consumer can also renew the lock for slow work. Kafka 4.2 (February 2026) declared them production-ready.
Kafka tracks a delivery count per record, so a record that keeps failing is archived after a limit (the group config share.delivery.count.limit, 5 by default). Kafka 4.4 added dead-letter queues for share groups: once the cluster's share.version feature is at 2, set errors.deadletterqueue.topic.name on the group and those records are written there instead of being dropped. The Java client class is KafkaShareConsumer. Spring for Apache Kafka added share consumers in 4.0 and gave them full production support in 4.1, through ShareKafkaListenerContainerFactory and ShareAcknowledgment.
When would you use a share group instead of a consumer group?
Use a share group when each record is an independent job, order does not matter, and you want to scale consumers beyond the partition count, for example sending emails or resizing images. Keep a consumer group when per-key ordering matters, when you need offset-based replay, or for stream processing. Share groups give no ordering guarantee.
Operations questions for experienced developers
How many partitions should a topic have?
Enough for your target throughput and consumer parallelism, with headroom, but not hundreds "just in case". Estimate from the throughput one consumer can handle: if one instance processes 2,000 records per second and you need 10,000 at peak, you need at least 5 partitions, so 6 to 12 is reasonable. Every partition adds files, memory, and replication work.
Can you reduce the number of partitions of a topic?
No. You can only increase it with kafka-topics.sh --alter --partitions. To shrink, create a new topic with fewer partitions and migrate producers and consumers to it. Even increasing has a cost: keyed records start landing on different partitions, so per-key ordering is broken across the change.
Which Kafka metrics do you watch in production?
- Consumer lag per group and partition, and its trend.
- Under-replicated partitions and ISR shrink and expand rates: anything above zero for long means a broker or disk problem.
- Offline partitions (must be zero) and active controller count.
- Request latency for produce and fetch, and producer error and retry rates.
- Disk usage per broker, because a full disk stops the broker.
How do you reprocess messages from the past?
Reset the group's offsets with kafka-consumer-groups.sh --reset-offsets, using --to-earliest, --to-offset or --to-datetime, followed by --execute; the group must be inactive while you do it. Or start a new consumer group with auto.offset.reset=earliest. Either way the data must still be within retention, and the consumers must handle duplicates.
What is the largest message Kafka accepts?
About 1 MB by default, controlled by the broker's message.max.bytes (or the topic's max.message.bytes) and the producer's max.request.size. You can raise them, but large messages hurt throughput and memory. The common pattern is to store the payload in object storage and send a reference (claim check).
Kafka interview questions for Spring Boot
How do you send and receive messages with Spring Kafka?
Spring Boot auto-configures a KafkaTemplate for sending and a listener container factory for @KafkaListener methods, both driven by spring.kafka.* properties. The listener container runs the poll loop, deserializes records, calls your method and commits offsets.
@Service
class OrderEvents {
private final KafkaTemplate<String, OrderPlaced> kafka;
OrderEvents(KafkaTemplate<String, OrderPlaced> kafka) {
this.kafka = kafka;
}
void publish(OrderPlaced event) {
kafka.send("orders", event.orderId(), event); // key = orderId keeps per-order ordering
}
@KafkaListener(topics = "orders", groupId = "billing", concurrency = "3")
void onOrder(OrderPlaced event) {
// runs on one of 3 consumer threads; each thread owns some partitions
}
}In Spring Kafka 3 and later, send() returns a CompletableFuture<SendResult>, not the old ListenableFuture. That detail shows you have used a current version.
What does concurrency on @KafkaListener mean?
concurrency = "3" creates three consumers (threads) in the same group inside one application instance. Partitions are split across them. Running 2 instances with concurrency 3 gives 6 consumers, so a 6-partition topic is fully used; more than that and threads sit idle.
How do you handle errors and dead-letter topics in Spring Kafka?
Register a DefaultErrorHandler with a back-off and a DeadLetterPublishingRecoverer. The handler retries the failed record in place a few times, then the recoverer publishes it to a dead-letter topic (by default the original topic name plus -dlt) and the container moves on. Mark exceptions that retrying cannot fix, such as validation errors, as not retryable.
@Bean
DefaultErrorHandler kafkaErrorHandler(KafkaTemplate<Object, Object> template) {
var recoverer = new DeadLetterPublishingRecoverer(template);
var handler = new DefaultErrorHandler(recoverer, new FixedBackOff(1_000L, 2));
handler.addNotRetryableExceptions(IllegalArgumentException.class);
return handler;
}Spring Boot wires a CommonErrorHandler bean into its auto-configured listener container factory. Blocking retries hold up the whole partition, so for long back-offs use non-blocking retries with @RetryableTopic, which sends failed records to retry topics and keeps the main topic moving.
What are the acknowledgement modes in Spring Kafka?
The container's AckMode decides when offsets are committed. BATCH (the default) commits after all records from one poll are processed; RECORD commits after each record; MANUAL and MANUAL_IMMEDIATE let the listener call Acknowledgment.acknowledge(). Set it with spring.kafka.listener.ack-mode, or per listener with the ackMode attribute.
How do you use Kafka transactions in Spring Boot?
Set spring.kafka.producer.transaction-id-prefix. Spring Boot then creates a transactional producer factory and a KafkaTransactionManager, and a listener container started with it runs each delivery inside a Kafka transaction, sending offsets to the transaction for you. Remember that this covers Kafka only; a database write in the same method is a separate transaction.
How do you test Kafka code in Spring Boot?
Use Testcontainers with a real Kafka broker (the apache/kafka image runs in KRaft mode) and @ServiceConnection, or @EmbeddedKafka from spring-kafka-test for faster in-JVM tests. Testcontainers is closer to production, which matters for serialization, transactions and error handling. Our own Spring Boot 4.1 backend runs its integration tests on Testcontainers too.
What the interviewer is checking: whether you have run Spring Kafka in production. Talking about poison records, dead-letter topics, retry back-off and idempotent listeners beats reciting annotation names.
Comparisons: Kafka vs RabbitMQ and friends
What is the difference between Kafka and RabbitMQ?
Kafka is a replicated log: records stay after they are read, consumers track their own offsets, ordering is per partition, and many groups can replay the same data. RabbitMQ is a message broker: exchanges route messages to queues, and a message is removed once a consumer acknowledges it. Kafka fits event streams and high volume; RabbitMQ fits task queues and flexible routing.
- Model: Kafka is a distributed, replicated log; RabbitMQ is a broker with exchanges and queues.
- After reading: Kafka keeps the record until retention ends; RabbitMQ removes it once acked (classic and quorum queues).
- Replay: Kafka can reset offsets; a normal RabbitMQ queue cannot, though RabbitMQ streams can.
- Ordering: Kafka orders per partition; RabbitMQ orders per queue, and redelivery can reorder.
- Routing: Kafka routes by topic and key; RabbitMQ has direct, topic, fanout and headers exchanges.
- Scaling reads: Kafka scales by partitions, or by share groups since 4.2; RabbitMQ uses competing consumers on one queue.
Why not use a database table as a queue instead of Kafka?
A table with a status column works for low volume and gives you transactions with your data for free. It breaks down with many consumers (lock contention), high write rates and multiple independent readers. That is why the outbox pattern uses a table only as a short-lived buffer and relays rows to Kafka.
When should you use Kafka Streams instead of a plain consumer?
A plain consumer is enough for "read a record, do something". Kafka Streams is a library for stateful processing: joins, windowed aggregations and local state stores backed by changelog topics, with exactly-once support. It runs inside your application, with no separate cluster to operate.
Practise with the full question bank
This page covers the questions that come up most. For a deeper set with model answers, the Apache Kafka with Spring Boot: 100 Interview Questions and Answers guide covers partitions and replication, producers, consumer groups, delivery semantics, Spring Kafka error handling, schemas and operations.
Kafka questions often turn into microservices design questions. Microservices Patterns: 60 Scenario Interview Questions covers sagas and the outbox, retries and circuit breakers, poison messages and duplicate payments.
Related reading
- Kafka scenario-based interview questions: duplicates, ordering, lag and data loss, the way interviewers phrase them.
- Kafka consumer groups, partitions and rebalancing explained, with diagrams.
- Spring Boot Kafka example: producer, consumer, retries and a dead-letter topic.
Official sources used for this guide: the Kafka 4.0 release announcement, the Kafka 4.2 release announcement, the producer configuration reference and the Spring for Apache Kafka share consumer docs.
FAQ
Is ZooKeeper still asked about in Kafka interviews?
Mostly as "what replaced it and why". Know that Kafka 4.0 removed ZooKeeper, that KRaft controllers store metadata in a Raft log, and that ZooKeeper clusters migrate on a 3.x bridge release. Deep ZooKeeper internals are no longer worth your preparation time.
What are the most common Kafka interview questions for experienced developers?
Delivery guarantees and how to get exactly-once, what happens during a rebalance, how to avoid data loss (acks, ISR, min.insync.replicas), handling poison messages, consumer lag, choosing partition counts and keys, and the outbox pattern. Expect follow-ups built on a real incident.
Which Kafka version should I mention in a 2026 interview?
Kafka 4.x. Say that 4.0 removed ZooKeeper and made the KIP-848 consumer protocol generally available, and that 4.2 made share groups production-ready. Kafka 4.4 is the newest release as of October 2026.
Does Kafka guarantee exactly-once delivery by default?
No. The defaults give an idempotent producer and at-least-once consumption if you commit after processing. Exactly-once needs transactions and read_committed consumers, and it only covers Kafka-to-Kafka flows.
How many Kafka questions should I prepare for a Spring Boot interview?
The 50 or so on this page cover most rounds. Add a few scenarios you can tell from your own work, for example a duplicate or lag problem you fixed, because interviewers for experienced roles usually move from definitions to "tell me about a time".




