Skip to content

Apache Kafka Cheat Sheet

Kafka is a distributed log: producers append records to topics partitioned for parallelism; consumers read via consumer groups with offset tracking.

How to use this Apache Kafka cheat sheet

Topics split into partitions ordered by offset. Producers choose partition by key hash or round-robin. KafkaJS is the common Node.js client for producers and consumers with configurable acks and retry semantics.

Consumer groups assign partitions exclusively per member—rebalance on join/leave. Idempotent producers and exactly-once semantics require enable.idempotence and transactional settings. Monitor lag and use dead-letter topics for poison messages.

Quick Apache Kafka example

import { Kafka } from 'kafkajs';

const kafka = new Kafka({ clientId: 'my-app', brokers: ['localhost:9092'] });
const producer = kafka.producer({ allowAutoTopicCreation: false });
await producer.connect();
await producer.send({
  topic: 'orders',
  messages: [{ key: 'user-42', value: JSON.stringify({ id: 1, total: 99 }) }],
});

Topics, Partitions & Offsets

Concept Example Notes
Topic orders Named stream of records
Partition orders-0, orders-1 Ordered log; parallelism unit
Offset partition 0, offset 1042 Monotonic position within partition
Key key: "user-42" Same key → same partition (ordering per key)
Retention retention.ms=604800000 Time or size-based log trimming
Replication replication.factor=3 Copies for fault tolerance
ISR In-sync replicas Leader acknowledges only ISR followers
Compaction cleanup.policy=compact Keep latest record per key (changelog topics)

KafkaJS Producer & Consumer

API Example Notes
Kafka client new Kafka({ clientId, brokers }) Shared config for producer/consumer/admin
producer.connect await producer.connect() Call once at startup
producer.send send({ topic, messages: [{ key, value }] }) Batch send multiple messages
consumer.connect await consumer.connect() Separate lifecycle from producer
subscribe consumer.subscribe({ topic: "orders", fromBeginning: false }) Join consumer group for topic
run eachMessage eachMessage: async ({ topic, partition, message }) => {} Auto commit unless manual
manual commit autoCommit: false + commitOffsets At-least-once with processing guarantee
disconnect await consumer.disconnect() Graceful shutdown on SIGTERM

Acks & Consumer Groups

Setting Example Effect
acks=0 Fire and forget No broker ack; may lose messages
acks=1 Leader ack only Risk loss if leader fails before replication
acks=all acks: -1 in KafkaJS Wait for all ISR replicas
group.id groupId: "order-processors" Consumers with same id share partitions
Rebalance On member join/leave Partitions reassigned; pause processing during rebalance
Static membership group.instance.id Reduce unnecessary rebalances
Partition assignor Range, RoundRobin, Sticky Sticky minimizes movement on rebalance
Consumer lag offset lag per partition Alert when processors fall behind producers

Idempotence & Reliability

Feature Example Notes
Idempotent producer enable.idempotence: true Deduplicate retries within session
max.in.flight maxInFlightRequests: 5 With idempotence, safe <= 5
Retries retry: { retries: 5 } Transient broker errors auto-retry
Dead letter topic Route failed messages after N retries Prevent poison pill blocking partition
Schema registry Avro/Protobuf with Confluent schema ID Evolve payloads with compatibility checks
Transactions consume-transform-produce atomic Exactly-once across topics (heavier overhead)
Headers messages: [{ headers: { traceId: "abc" } }] Metadata without parsing value
Timestamp LogAppendTime vs CreateTime Broker vs producer timestamp semantics

Consumer with manual commit

await consumer.run({
  autoCommit: false,
  eachMessage: async ({ topic, partition, message }) => {
    await processMessage(message);
    await consumer.commitOffsets([
      { topic, partition, offset: (Number(message.offset) + 1).toString() },
    ]);
  },
});

Commit only after successful processing for at-least-once semantics.

Producer with idempotence

const producer = kafka.producer({
  idempotent: true,
  maxInFlightRequests: 5,
  retry: { retries: 5 },
});

Requires acks=all and enables deduplication of producer retries.

Admin create topic

const admin = kafka.admin();
await admin.connect();
await admin.createTopics({
  topics: [{ topic: 'orders', numPartitions: 6, replicationFactor: 3 }],
});
await admin.disconnect();

Disable allowAutoTopicCreation in production; provision topics explicitly.

Common mistakes

  • Using auto-commit before processing finishes, losing messages on crash.
  • Too few partitions limiting consumer parallelism for high-throughput topics.
  • Ignoring consumer lag until processing is hours behind production traffic.
  • Sending giant messages near the 1 MB default limit instead of referencing S3.

Key takeaways

  • Partition by key for ordering; increase partitions for throughput.
  • Use acks=all and idempotent producers for durable writes.
  • Consumer groups scale horizontally; one consumer per partition max.
  • Manual commits after processing give at-least-once delivery you control.

Pro Tip

Start with at-least-once plus idempotent consumers (dedupe by message key)—exactly-once transactions add complexity most apps do not need.