Before you use this reference
This page is a lookup, not a tutorial. The explanations live in
Kafka Fundamentals,
Topics, Partitions, and Offsets,
Running Kafka Locally,
Producing Messages with Python, and
Consuming Messages with Python.
The client library is confluent-kafka.
Connect from where#
| From | Bootstrap address |
|---|---|
| Host machine | 127.0.0.1:9092 |
| Another container | kafka:29092 |
| Kafka UI | http://localhost:8085 |
| CLI inside the broker container | localhost:29092 |
Producer skeleton#
import jsonfrom confluent_kafka import Producer
producer = Producer({ "bootstrap.servers": "localhost:9092", "enable.idempotence": True, "acks": "all", "linger.ms": 10,})
def on_delivery(err, msg): if err is not None: print(f"delivery failed: {err}")
for event in events: producer.produce( topic="order-events", key=str(event["customer_id"]).encode("utf-8"), value=json.dumps(event).encode("utf-8"), on_delivery=on_delivery, ) producer.poll(0)
remaining = producer.flush(timeout=10)Consumer skeleton#
import jsonfrom confluent_kafka import Consumer
consumer = Consumer({ "bootstrap.servers": "localhost:9092", "group.id": "warehouse-sink", "auto.offset.reset": "earliest", "enable.auto.commit": False,})consumer.subscribe(["order-events"])
batch = []try: while True: msg = consumer.poll(timeout=1.0) if msg is None: continue if msg.error(): continue
try: event = json.loads(msg.value().decode("utf-8")) except ValueError: continue # route to a dead-letter destination instead
batch.append(event) if len(batch) >= 100: write_batch(batch) # write first consumer.commit(asynchronous=False) # then commit batch.clear()except KeyboardInterrupt: passfinally: if batch: write_batch(batch) consumer.commit(asynchronous=False) consumer.close()Producer config keys#
| Key | Meaning |
|---|---|
bootstrap.servers | Broker address(es), comma-separated |
enable.idempotence | True: retries do not create duplicate appends |
acks | all (in-sync replicas) / 1 (leader) / 0 (fire and forget) |
linger.ms | Wait this long to batch more records per request |
batch.size | Max bytes per partition batch |
compression.type | none / lz4 / zstd |
queue.buffering.max.messages | In-memory send-queue size; produce() raises BufferError when full |
message.max.bytes | Max size of a single record |
Consumer config keys#
| Key | Meaning |
|---|---|
bootstrap.servers | Broker address(es) |
group.id | Consumer group name (required) |
auto.offset.reset | earliest / latest; used only when no committed offset exists |
enable.auto.commit | True commits on a timer; False to commit manually |
auto.commit.interval.ms | How often auto-commit runs (default 5000) |
max.poll.interval.ms | Max gap between poll() calls before a rebalance (default 300000) |
session.timeout.ms | How long the group waits before declaring a member dead |
fetch.min.bytes / fetch.max.wait.ms | Batch reads from the broker |
Message object#
| Method | Returns |
|---|---|
msg.value() / msg.key() | Payload / key as bytes (or None) |
msg.topic() | Topic name |
msg.partition() | Partition number |
msg.offset() | Offset in the partition |
msg.timestamp() | (type, ms) tuple |
msg.headers() | List of (key, bytes) or None |
msg.error() | None, or a KafkaError to handle |
Topic config keys#
| Key | Meaning |
|---|---|
retention.ms | Delete records older than this (e.g. 604800000 = 7 days) |
retention.bytes | Delete oldest segments once a partition exceeds this size |
cleanup.policy | delete (age/size) or compact (keep latest value per key) |
partitions | Number of partitions (increase only) |
replication.factor | Copies per partition (1 locally) |
min.insync.replicas | With acks=all, minimum replicas that must ack a write |
kafka-topics CLI#
kafka-topics --bootstrap-server localhost:29092 --listkafka-topics --bootstrap-server localhost:29092 \ --create --topic order-events --partitions 3 --replication-factor 1kafka-topics --bootstrap-server localhost:29092 --describe --topic order-eventskafka-topics --bootstrap-server localhost:29092 --alter --topic order-events --partitions 6kafka-configs CLI#
kafka-configs --bootstrap-server localhost:29092 \ --alter --entity-type topics --entity-name order-events \ --add-config retention.ms=259200000
kafka-configs --bootstrap-server localhost:29092 \ --describe --entity-type topics --entity-name order-eventskafka-consumer-groups CLI#
kafka-consumer-groups --bootstrap-server localhost:29092 --listkafka-consumer-groups --bootstrap-server localhost:29092 --describe --group warehouse-sinkkafka-consumer-groups --bootstrap-server localhost:29092 \ --group warehouse-sink --topic order-events \ --reset-offsets --to-earliest --execute--describe shows CURRENT-OFFSET, LOG-END-OFFSET, and LAG per partition.
Console tools#
kafka-console-producer --bootstrap-server localhost:29092 --topic order-eventskafka-console-consumer --bootstrap-server localhost:29092 --topic order-events --from-beginningJSON message contract skeleton#
{ "order_id": 101, // business key: unique, used for de-duplication "customer_id": 1, // partition key: keeps a customer's events ordered "created_at": "2026-01-04T09:12:00", "amount": 1200.0, "schema_version": 1 // bump on an incompatible change}Rules: additive changes only without coordination; document required fields; version explicitly for incompatible changes.
Common errors#
| Error / symptom | Cause | Fix |
|---|---|---|
BufferError: Local: Queue full | Producing faster than the client sends | poll() more often, raise queue.buffering.max.messages, or slow down |
| "Message timed out" in a delivery report | Broker unreachable or wrong advertised listener | Check bootstrap.servers and listener config for your location |
MSG_SIZE_TOO_LARGE | Record exceeds message.max.bytes | Shrink payload, store blob elsewhere, or raise the limit |
| Consumer reads nothing | Committed offset at the end, or auto.offset.reset=latest on a fresh group | New group.id, or --reset-offsets --to-earliest |
| Frequent rebalances | Processing exceeds max.poll.interval.ms between polls | Smaller batches / faster work / raise the interval |
| Connects then hangs | Used localhost from a container, or kafka:29092 from the host | Match the address to where the client runs |