Kafka & Microservices Interview Questions
Producers, consumers, reliability, transactions & production deployment
← Learn this topic from scratch firstKafka Fundamentals
What is a Kafka partition, and why does it matter for both ordering and scaling?
beginnerA topic is split into partitions, each an independently ordered, append-only log. Kafka only guarantees message order WITHIN a single partition, not across the whole topic, and partitions are the unit of parallelism — more partitions mean more consumers in a group can read concurrently, which is why partition count is a key scaling and ordering-tradeoff decision made up front.
What's the difference between a Kafka topic and a queue like RabbitMQ, conceptually?
beginnerA traditional queue removes a message once it's consumed — one consumer, one delivery. A Kafka topic retains messages for a configured retention period regardless of consumption, and multiple independent consumer groups can each read the entire topic from their own position, so the same event can be replayed or consumed by many different downstream systems without them interfering with each other.
Running Kafka Locally
Why did Kafka move away from requiring a separate ZooKeeper cluster (KRaft mode)?
beginnerZooKeeper was a second distributed system to operate, monitor, and scale alongside Kafka itself, doubling operational complexity. KRaft mode has Kafka brokers manage cluster metadata and consensus themselves using the Raft protocol, removing the separate ZooKeeper dependency entirely and simplifying both local development and production deployment.
Why is running Kafka locally via Docker Compose the standard approach instead of installing it natively?
beginnerKafka has several moving parts (broker, and previously ZooKeeper) with specific version compatibility requirements — Docker Compose lets you declare the exact versions and configuration as code, spin the whole stack up/down with one command, and avoid polluting your local machine with a long-running native Kafka install that's easy to misconfigure or forget about.
Producer & Consumer Internals
What does a Kafka producer's `acks` setting control, and what's the trade-off between `acks=1` and `acks=all`?
beginnerPro`acks` controls how many broker replicas must confirm they've written a message before the producer considers it 'sent successfully.' `acks=1` only waits for the partition leader (faster, but a message can be lost if the leader crashes before replicating), while `acks=all` waits for all in-sync replicas (slower, but the message survives a leader failure) — a classic throughput-vs-durability trade-off.
Why does a Kafka consumer track its own 'offset' instead of the broker tracking what each consumer has read?
beginnerProStoring the offset with the consumer (in an internal Kafka topic, `__consumer_offsets`) lets each consumer group track its own independent read position on the same topic, and lets a consumer resume exactly where it left off after a restart or rebalance — the broker doesn't need to know or care which consumers exist, keeping it simpler and more scalable.
The Library Inventory System
Why design a system around a producer/consumer split (e.g. an inventory-update producer and a search-index consumer) instead of one service doing everything?
beginnerProSplitting them lets each service scale, deploy, and fail independently — a slow search-indexing process doesn't block inventory updates from being accepted, and if the indexing consumer crashes, events simply queue up in Kafka until it recovers, rather than inventory updates themselves failing.
What's a risk of designing microservice boundaries around Kafka topics without thinking through ownership first?
beginnerProIf it's unclear which service 'owns' writing to a given topic (its schema, its meaning), multiple producers can end up disagreeing about what a message means or its exact shape, causing consumers to break unpredictably — clear single-writer ownership per topic is a foundational microservices-with-Kafka design decision, not an afterthought.
AI-Assisted / Agentic Engineering
What's a practical risk of using an AI coding assistant to generate Kafka consumer/producer boilerplate without review?
beginnerProAI-generated code can look syntactically correct while getting subtle but critical details wrong — e.g. forgetting to handle a `CommitFailedException` on rebalance, or using an `acks` setting inconsistent with the durability the feature actually needs — and these mistakes often only surface under real failure conditions in production, not in a quick local test.
Why is reviewing an AI-generated Kafka consumer's error-handling logic especially important compared to reviewing typical CRUD code?
beginnerProKafka consumer failure modes are non-obvious (poison-pill messages that fail forever and block the partition, at-least-once delivery causing silent duplicate processing) — code that looks fine on the happy path can silently degrade an entire consumer group's throughput or correctness in ways that don't show up until a specific edge case occurs in production.
Building the Producer Microservice
Why send Kafka messages asynchronously (with a callback) rather than blocking on every `send()` call?
beginnerProBlocking on every send serializes your throughput to the network round-trip time per message, which is far slower than Kafka is capable of. Sending asynchronously with a callback for success/failure lets the producer batch and pipeline many in-flight sends at once, dramatically increasing throughput, while still letting you react to failures per-message.
Why does the choice of a message key (not just the value) matter when producing to a partitioned topic?
beginnerProKafka uses the key's hash to deterministically choose which partition a message lands in, which means all messages with the same key (e.g. the same `orderId`) always go to the same partition and are therefore processed IN ORDER relative to each other. No key means round-robin partitioning with no ordering guarantee across messages about the same entity.
Testing the Producer
Why is testing against an embedded/in-memory Kafka broker preferred over mocking the `KafkaTemplate` entirely?
beginnerProMocking `KafkaTemplate` only proves your code CALLED send() with the right arguments — it says nothing about serialization actually working, whether your message satisfies the topic's schema, or whether the producer config itself is valid. An embedded broker (or Testcontainers Kafka) runs real serialization and a real (if temporary) broker, catching a whole class of bugs mocks can't see.
What's a common mistake when asserting on a produced message in an integration test?
beginnerProAsserting immediately after calling `send()` without waiting for the async send to actually complete — Kafka producers are asynchronous by default, so a test that checks a topic immediately can get a false failure (or false pass) due to a race condition; tests need to either use a synchronous send for testing or poll/await consumption with a timeout.
API Documentation with OpenAPI / Swagger
Why does an event-driven microservice still need REST API documentation via OpenAPI/Swagger?
beginnerProEven in an event-driven system, most services still expose synchronous REST endpoints for queries, admin operations, or triggering actions, and other teams/services integrating with those endpoints need accurate, generated-from-code documentation rather than a hand-written doc that drifts out of sync with the actual implementation over time.
What's the main advantage of generating OpenAPI docs from annotated code (springdoc-openapi) versus hand-writing a spec file?
beginnerProHand-written specs inevitably drift out of sync as the code evolves, since nothing forces them to stay updated. Annotation-driven generation (`@Operation`, `@Schema`) derives the spec directly from the actual controller code at build/runtime, so the documentation can never describe an endpoint shape that doesn't match reality.
Building the Consumer Microservice
What does 'consumer group' mean, and why does adding more consumer instances only help scaling up to a point?
intermediateProA consumer group is a set of consumer instances that jointly consume a topic, with each partition assigned to exactly one consumer in the group at a time. Scaling helps only up to the number of partitions — once you have as many consumer instances as partitions, adding more consumers leaves them idle, since a partition can't be split further across two consumers in the same group.
Why is manual offset commit (rather than auto-commit) often preferred for a consumer doing meaningful processing?
intermediateProAuto-commit advances the offset on a timer regardless of whether your processing actually succeeded, so a crash mid-processing can mean that message is never retried (it's already marked as consumed). Manual commit lets you commit the offset only AFTER your processing logic completes successfully, so a failure leaves the offset uncommitted and the message gets redelivered on restart.
Persistence Layer
Why does a Kafka consumer that writes to a database need to think about idempotency, not just 'save the record'?
intermediateProKafka's at-least-once delivery (the default, safest guarantee without extra work) means the SAME message can be delivered and processed more than once, e.g. after a consumer restart before it committed its offset. Without an idempotency check (like a unique constraint on an event ID, or an upsert instead of a blind insert), a redelivered message can create duplicate rows or double-apply an effect.
Why might a consumer intentionally write to a local database inside the SAME transaction as committing its Kafka offset?
intermediateProCommitting the Kafka offset and writing to the database are two separate systems — if the DB write succeeds but the app crashes before committing the offset, the message gets reprocessed (safe if idempotent); but if you want to avoid ANY duplicate processing risk, the 'offset commit as part of the DB transaction' pattern (rare, needs manual offset storage in the DB itself) ties both operations to one atomic outcome.
Testing the Consumer with Embedded Kafka
Why is `@EmbeddedKafka` valuable for testing a Kafka consumer's rebalancing or retry behavior specifically?
intermediateProThose behaviors only emerge from real broker interactions (partition assignment protocol, actual redelivery on uncommitted offsets) that a mock can't simulate. `@EmbeddedKafka` spins up a real (in-process) broker for the test, so you can genuinely trigger a rebalance or force a redelivery and assert the consumer handles it correctly, not just that its code compiles.
What's a common flaky-test cause when testing Kafka consumers, and how is it usually fixed?
intermediateProAsserting immediately after producing a test message, before the consumer (running on its own poll thread) has actually had a chance to process it — a race condition that passes sometimes and fails other times depending on timing. The fix is using a polling `Awaitility`-style assertion (retry the assertion for up to N seconds) instead of a single immediate check.
CRUD & Exposing Data
In a system fed by Kafka events, why do CRUD read endpoints usually query a local database rather than Kafka directly?
intermediateProKafka topics aren't optimized for ad-hoc queries (filter, sort, paginate) — they're an ordered log meant to be consumed sequentially. The standard pattern is a consumer that persists incoming events into a queryable local database (essentially a materialized view of the event stream), and REST read endpoints query that database, not the topic itself.
Why might a write ('create') endpoint in an event-driven service publish to Kafka instead of writing directly to its own database?
intermediateProPublishing the write as an event lets multiple independent downstream consumers react to it (search indexing, notifications, analytics) without the write endpoint needing to know about or call each of them directly — the producer stays decoupled from however many things eventually care about that write.
Producer Reliability & Errors
What's the difference between a retriable and a non-retriable producer error in Kafka, and why does that distinction matter?
intermediateProA retriable error (like a temporary leader-election in progress) is transient and safe to automatically retry — the Kafka producer client can handle this internally with configured retries. A non-retriable error (like a message exceeding the configured max size) will fail identically no matter how many times you retry, so blindly retrying it just wastes time and delays surfacing a real problem that needs code/config changes.
Why can naive automatic retries on a Kafka producer introduce message duplication, and how does Kafka's idempotent producer fix it?
intermediateProIf a send succeeds on the broker side but the acknowledgment is lost in transit, a naive retry resends the same logical message, creating a duplicate on the broker. The idempotent producer (`enable.idempotence=true`) tags each message with a sequence number per producer session, letting the broker detect and silently drop an exact duplicate retry instead of writing it twice.
Consumer Errors, Retry & Recovery
What is a 'poison pill' message in Kafka consumer processing, and why is it dangerous if not handled?
intermediateProA poison pill is a message that causes processing to fail every single time it's retried (e.g. malformed data that always throws a parse exception) — without special handling, a naive retry-forever consumer gets stuck reprocessing that same message endlessly, blocking every message behind it on that partition from ever being processed.
What's the standard pattern for handling a message that fails processing repeatedly, without blocking the whole partition?
intermediateProRoute it to a dead-letter topic (DLT) after a bounded number of retries — the consumer publishes the failing message (plus error context) to a separate topic for later inspection/manual reprocessing, then commits its offset and moves on, so one bad message doesn't stall the healthy ones behind it.
Consumer Timing Configurations
What does `max.poll.interval.ms` actually protect against, and what happens if a consumer exceeds it?
intermediateProIt's the maximum time allowed between successive calls to `poll()` — if your processing logic between polls takes longer than this (e.g. a slow downstream call), Kafka assumes the consumer instance is stuck or dead and triggers a rebalance, reassigning its partitions to other consumers, which can cause the 'stuck' consumer to have its work duplicated once it finally does respond.
Why does increasing `max.poll.records` improve throughput but also increase the risk of rebalance-triggered reprocessing?
intermediateProA higher `max.poll.records` means each `poll()` call returns more messages to process before the next `poll()`, improving batch efficiency — but processing a bigger batch also takes longer, increasing the odds of exceeding `max.poll.interval.ms` if the batch's total processing time isn't accounted for, which can trigger an unwanted rebalance mid-batch.
Transactions & Exactly-Once Semantics
What does Kafka's 'exactly-once semantics' (EOS) actually guarantee, and what's the common misconception?
advancedProEOS guarantees each message is processed and its effects committed exactly once WITHIN the Kafka ecosystem (producer-to-topic, and read-process-write consumer-to-topic patterns) using Kafka transactions. The common misconception is thinking this extends automatically to external side effects like a database write or an outbound HTTP call — those still need idempotency handling separately, since Kafka's transaction can't span an external system.
Why does a 'read-process-write' consumer pattern need Kafka transactions to achieve exactly-once, not just idempotent producers?
advancedProIdempotent producers alone only prevent duplicate writes from producer retries — they don't atomically tie together 'I consumed this input message' with 'I produced this output message' as one unit. Kafka transactions wrap both the input offset commit and the output produce into a single atomic operation, so a crash between the two can't leave the system having produced output without ever recording that the input was consumed (or vice versa).
Health, Monitoring & Observability
Why is 'consumer lag' one of the single most important metrics to monitor in a Kafka-based system?
advancedProLag (how far behind the latest produced offset a consumer's current offset is) is the earliest and clearest signal that a consumer is falling behind — whether from a slow downstream dependency, an unhandled exception loop, or simply insufficient consumer instances for the load. Rising lag predicts user-facing staleness before any other symptom becomes visible.
What does a Spring Boot Actuator health check for Kafka actually verify, and why might a service still be 'unhealthy' even if it's technically running?
advancedProIt typically verifies the application can reach the Kafka broker (a lightweight connectivity/metadata check). A service can be 'up' as a process yet unable to produce or consume anything useful if it's lost broker connectivity — surfacing that as an explicit unhealthy state lets Kubernetes stop routing traffic to it rather than silently failing requests.
Packaging & Running Standalone
Why does packaging a Spring Boot app as an executable 'fat jar' matter for deploying a Kafka microservice?
advancedProA fat jar bundles the application plus every dependency (Kafka client library, Spring libraries) into one self-contained file runnable with just `java -jar`, so deployment doesn't require separately installing a matching set of dependency jars on the target machine — the artifact IS the deployable unit.
What's a common misconfiguration when running a packaged Kafka consumer app standalone (outside Docker Compose) for the first time?
advancedProPointing `bootstrap.servers` at `localhost:9092` when the app is actually running in an environment where Kafka is reachable at a different hostname/port (e.g. a Docker service name or a remote broker) — this is one of the most common 'works on my machine but not elsewhere' Kafka connectivity bugs, since the client fails silently-ish with connection retries rather than a clear error.
Containerization with Docker
Why does a Dockerized Kafka consumer service need explicit health checks defined in its Dockerfile/Compose config?
advancedProWithout one, Docker/Kubernetes only knows if the PROCESS is running, not whether it's actually able to connect to Kafka or process messages — a health check endpoint (backed by Actuator) that verifies real broker connectivity lets the orchestrator detect and restart a container that's alive but functionally stuck.
Why is minimizing a Kafka microservice's Docker image size still worth the effort even though storage is cheap?
advancedProSmaller images pull faster during deployments and autoscaling events (a slow image pull directly delays how fast Kubernetes can spin up a new consumer instance to handle a lag spike), and a smaller image also has a smaller attack surface, since fewer unnecessary packages/layers means fewer potential vulnerabilities.
Kubernetes Deployment
Why does scaling a Kafka consumer's Kubernetes Deployment beyond the topic's partition count not improve throughput?
advancedProKafka assigns each partition to exactly one consumer within a consumer group at a time — if you have more pod replicas than partitions, the extra pods simply sit idle with no partitions assigned, since a single partition cannot be split across two consumers in the same group.
What Kubernetes concept maps naturally onto 'a consumer instance that needs a stable identity across restarts', and why might that matter for Kafka?
advancedProA `StatefulSet` gives each pod a stable, predictable network identity and ordinal index across restarts, which matters if you rely on that identity for manual partition assignment or for correlating a specific consumer instance with monitoring/logs — a plain `Deployment`'s pods get arbitrary, changing names on every restart, which works fine for most Kafka consumers but not ones that need pinned identity.
Kafka Security (SSL/TLS)
Why does Kafka broker-to-client communication need TLS encryption in production, beyond just 'security best practice'?
advancedProWithout TLS, both the message payloads AND consumer group / topic metadata travel in plaintext across the network — anyone with network access between the client and broker could read message contents (potentially sensitive business data) or credentials used for SASL authentication, which is a real, exploitable risk on any shared or cloud network.
What's the difference between Kafka's SSL/TLS (encryption) and SASL (authentication), and why do production clusters typically need both?
advancedProTLS encrypts the data in transit so it can't be read or tampered with on the wire, but by itself doesn't verify WHO is connecting. SASL (e.g. SCRAM or Kerberos) handles authenticating the client's identity to the broker. Production clusters typically run both together — TLS for confidentiality/integrity, SASL for verifying the connecting client is who it claims to be — since either alone leaves a real gap.
Capstone & Synthesis
When designing a full producer-to-consumer pipeline (produce, persist, retry, DLT, monitor), what's the most common architectural mistake teams make early on?
advancedProUnder-provisioning partition count upfront — since increasing partitions later changes the key-to-partition hash mapping, breaking the ordering guarantee for any key whose messages were relying on landing in the same partition, so partition count is one of the few Kafka decisions that's genuinely expensive to change after the fact.
Why does a production-grade Kafka pipeline treat 'exactly the message was delivered' as insufficient on its own, without also verifying business-level correctness?
advancedProDelivery guarantees (at-least-once, exactly-once) are a Kafka-level correctness property about the messaging layer, not a guarantee that your business logic correctly interpreted and acted on that message — a message can be delivered exactly once yet still be processed with a bug, so monitoring and testing need to validate business outcomes, not just delivery semantics.