Skip to main content

Kafka Producers & Consumers

Learn to build robust applications that publish and subscribe to Kafka topics. The Producer and Consumer APIs are where Kafka theory meets production reality — this is the code you will write, debug, and tune every day.

Producer API

Producers publish data to the topics of their choice.

Key Responsibilities

  • Partitioning: Deciding which partition to send the message to.
  • Serialization: Converting key/value objects to bytes.
  • Compression: Reducing network bandwidth (Snappy, Gzip, LZ4, Zstd).
  • Batching: Grouping messages for efficiency.

Java Example

Python Example (kafka-python)


Consumer API

Consumers read data from topics. They subscribe to one or more topics and pull data.

Consumer Groups & Rebalancing

  • Consumer Group: A pool of consumers that share the work.
  • Rebalancing: When a consumer joins/leaves, partitions are reassigned.

Java Example


Delivery Semantics

At Most Once

Messages may be lost, but never duplicated. Commit offset before processing.

At Least Once

Messages are never lost, but may be duplicated. Commit offset after processing. (Default/Preferred)

Exactly Once

Each message is delivered exactly once. Requires Transactional API.

Important Configurations

Producer Configs

Consumer Configs


Best Practices

Handle WakeupException and close consumers gracefully to trigger a rebalance immediately rather than waiting for a timeout.
Since “At Least Once” is common, ensure your processing logic handles duplicates (e.g., using a database unique constraint).
Consumer Lag is the difference between the latest offset in the partition and the consumer’s current offset. High lag means consumers are too slow.

Exactly-Once Semantics (EOS)

Exactly-once is the holy grail of message delivery. Kafka supports it through Idempotent Producers and Transactions.

Idempotent Producer

Prevents duplicates caused by producer retries.
How it works:
  • Producer assigns a Producer ID (PID) and sequence number to each message
  • Broker deduplicates based on PID + sequence number
  • If retry sends duplicate, broker recognizes and discards it

Transactional Producer

For atomic writes across multiple partitions/topics. The classic use case is the “consume-transform-produce” pattern: read from topic A, process, write to topic B, and commit the consumer offset — all atomically. Either everything succeeds or nothing does.

Transactional Consumer

Read only committed messages:

Consumer Group Rebalancing Deep Dive

Rebalancing is one of the most misunderstood Kafka concepts.

What Triggers Rebalancing?

  1. Consumer joins the group
  2. Consumer leaves the group (graceful or crash)
  3. Consumer fails to send heartbeat within session.timeout.ms
  4. Topic partition count changes
  5. Consumer subscription changes

Rebalancing Strategies

Configuring Cooperative Rebalancing

Preventing Unnecessary Rebalances

Interview Tip: Know the difference between session.timeout.ms and max.poll.interval.ms:
  • session.timeout.ms: Time without heartbeats before consumer is considered dead
  • max.poll.interval.ms: Time between poll() calls before consumer is kicked out

Producer Partitioning Strategies

Default Partitioner

Custom Partitioner


Offset Management

Manual vs Auto Commit

Best Practice: Commit After Processing

Seek to Specific Offset


Interview Questions & Answers

Exactly-once requires:
  • enable.idempotence=true
  • Transactional producer
  • isolation.level=read_committed for consumers
Diagnosis:
Solutions:
  1. Add consumers: More consumers = more parallelism (up to partition count)
  2. Increase partitions: Allows more consumers
  3. Optimize processing: Batch database writes, use async I/O
  4. Increase batch size: max.poll.records
  5. Skip old data: Reset offset to latest
If time between poll() calls exceeds max.poll.interval.ms:
  1. Consumer is considered dead
  2. Rebalance is triggered
  3. Partitions are reassigned
  4. Consumer may process same messages again (duplicates)
Fix: Increase max.poll.interval.ms or reduce max.poll.records
Within a partition: Guaranteed by KafkaFor a specific key: Use a key when producing
Gotcha with retries: Set max.in.flight.requests.per.connection=1 or use idempotent producer to prevent reordering on retry.
Best practice: Use commitAsync() in loop, commitSync() on shutdown:

Common Pitfalls

1. Auto-Commit with Slow Processing: If processing takes > 5s, offsets are committed before processing completes → data loss on crash.2. Not Handling Rebalancing: During rebalance, partitions are revoked. Commit offsets before they’re revoked or you’ll reprocess.3. Single-Threaded Processing: If one message is slow, all processing blocks. Consider async processing.4. max.poll.records Too High: Fetching 10,000 records but processing is slow → rebalance kicks you out.5. Not Monitoring Consumer Lag: Lag indicates consumers can’t keep up. Set up alerts!

Next: Kafka Streams →