Part 6 · Async & Event-Driven Systems

Apache Kafka Fundamentals

Thirty services all need each other's data, and the data team wants to replay last week. How Kafka's simple idea — a partitioned, replicated, append-only log — became the backbone of event streaming: topics, keys, offsets, consumer groups, retention and compaction.

Lesson 3612 min readintermediate#kafka#streaming

On this page

  1. The Problem
  2. The Core Idea
  3. How It Works
  4. Trade-offs
  5. In the Real World
  6. Interview Questions
  7. Key Takeaways
  8. Further Reading

The Problem

A growing company has 30 services (small programs that each do one job), and they all need to share data:

  • the order service must tell billing, shipping, analytics, search and fraud detection about every order,
  • the app sends millions of clicks and views per minute to analytics,
  • the data team wants to replay last week's events after fixing a bug in their pipeline.

With point-to-point connections, every system talks to every other system. It becomes a tangled web of integrations that nobody fully understands. Classic queues delete messages once they are read, so there is nothing to replay. And at millions of events per second, many traditional brokers (servers that store and deliver messages) struggle.

Apache Kafka solved this at LinkedIn. It became the backbone of event streaming at thousands of companies. An event is a record that something happened, such as "order placed". Event streaming means sending a continuous flow of events between systems. Kafka's secret is a simple idea: the log. A log is a list of records where you only add new ones at the end.

The Core Idea

Think about a bank passbook or a ship's logbook.

  • Entries are written in order, one after another.
  • You never erase or change an old entry. You only add new ones at the end.
  • Anyone can read the book from any page. The accountant reads today's entries, while an auditor goes back and reads from January.
  • Each reader keeps their own bookmark. One reader's position does not affect another's.

Kafka is a huge, distributed, append-only logbook for events. "Distributed" means it runs on many servers. "Append-only" means you can only add to the end:

  • Producers (programs that send events) append events to the end.
  • Consumers (programs that read events) read from wherever their bookmark (offset) is.
  • Events stay for days or even forever, so anyone can re-read history.

Instead of every service connecting to every other one, all services connect to Kafka:

Before — spaghetti
  • •every service integrates with every other
  • −n × (n − 1) connections to build and keep working
  • −nothing can be replayed
After — Kafka as the hub
  • •producers write once; consumers read at their own pace
  • +add a consumer without touching producers
  • +replay history whenever needed
From point-to-point spaghetti to one hub. · compare

How It Works

Topics, partitions and offsets

A topic is a named stream of events, like a folder for one kind of event. Examples: orders, payments or page-views.

Each topic is split into partitions. A partition is one ordered, append-only log. Each event in it gets a number that keeps growing, called its offset (its position in the log).

P0
01234567
P1
01234567
P2
01234567
P3
01234567
P4
01234567
P5
01234567
each box = one message at an offset; order is kept within a partition
Group A
consumer-1P0, P3
consumer-2P1, P4
consumer-3P2, P5
Group B: reads all 6 partitions again, at its own pace

Inside one group each partition has exactly one consumer, so the partition count caps your parallelism. Every extra group gets its own full copy of the stream: that is pub/sub.

A topic with partitions and a consumer group. Change the counts and see how partitions are assigned — and when consumers go idle. · interactive

Why partitions?

  • Scale. Partitions are spread across many servers, so a topic can hold far more data than one machine can.
  • Parallelism. Different consumers can read different partitions at the same time. Parallelism means doing many things at once.
  • Ordering. Kafka guarantees order within a partition, not across the whole topic.

Keys decide the partition

Every event can have a key, such as an order ID. A hash is a calculation that turns a key into a number. Kafka hashes the key to choose a partition, so all events with the same key go to the same partition, and stay in order:

Text
key = order_id "5521"  → hash → Partition 1:  created → paid → shipped   ✅ in orderkey = order_id "7730"  → hash → Partition 0:  created → cancelled         ✅ in order

Choosing the key is like choosing a shard key (lesson 25):

  • User ID → all of one user's events in order.
  • Order ID → each order's lifecycle in order.
  • No key → events are spread evenly, with no ordering guarantee.
  • A hot key (one very busy key, such as one huge customer) → one overloaded partition.

Brokers and replication

acks=0
don't wait
fastest; messages can be lost
acks=1
leader only
lost if the leader dies before followers copy it
acks=all
all in-sync replicas
with min.insync.replicas=2 — the setting for important data
The producer's acks setting decides how much a “success” is worth. · numbers

Kafka runs as a cluster (a group of servers that work together). Each server is called a broker. Each partition is replicated (copied) to several brokers, commonly 3:

Text
Partition 0:  Leader on Broker 1,  followers on Broker 2 and 3Partition 1:  Leader on Broker 2,  followers on Broker 3 and 1Partition 2:  Leader on Broker 3,  followers on Broker 1 and 2
  • The leader handles reads and writes for that partition. Followers copy it (single-leader replication, lesson 24).
  • The ISR (In-Sync Replicas) are the followers that are caught up with the leader.
  • If a leader's broker dies, an in-sync follower becomes the new leader.

Durability settings decide how safe writes are:

  • acks=0: the producer does not wait at all. (acks is the setting for how many brokers must confirm a write.) Fastest, and messages can be lost.
  • acks=1: wait for the leader only. The message is lost if the leader dies before followers copy it.
  • acks=all: wait for all in-sync replicas. Combined with min.insync.replicas=2 (with a replication factor of 3, meaning 3 copies), a write is confirmed only when at least two brokers have it. This is the setting for important data.

Metadata: from ZooKeeper to KRaft

Kafka needs to track which brokers are alive, who leads each partition, and topic configurations. For years this used Apache ZooKeeper, a separate system that stores shared settings and status. Kafka then built its own system based on Raft (a way for servers to agree), called KRaft. Kafka 4.0 removed ZooKeeper completely. The result is fewer parts to run and faster recovery.

Producers

Producers send events to topics. Features that matter:

  • Batching: collect many small messages and send them together (settings like linger.ms and batch.size), for much higher throughput.
  • Compression: compress batches (for example with lz4 or zstd) to save network and disk.
  • Idempotent producer: idempotent means repeating it has the same effect as doing it once. Kafka removes duplicates caused by producer retries, so a network retry does not write the same event twice. It is on by default in modern Kafka (since version 3.0).
  • Transactions: write to several partitions atomically (all succeed or none do; lesson 37).

Consumers and consumer groups

Consumers read events and track their offset, meaning "I have processed everything up to here".

Consumers work in consumer groups (lesson 35). A consumer group is a team of consumers that share the work of one topic:

  • Each partition is read by exactly one consumer in the group at a time.
  • Different groups read the same topic independently, each with its own offsets.
Text
Topic "orders" (4 partitions)Group "billing" (2 consumers):   consumer A ← P0, P1   consumer B ← P2, P3Group "analytics" (4 consumers):   c1 ← P0   c2 ← P1   c3 ← P2   c4 ← P3Group "search" (5 consumers):   4 get one partition each… the 5th is IDLE (no partition left)

Important rule: the number of partitions is the maximum parallelism for a consumer group. More consumers than partitions leaves some idle. Choose partition counts with future growth in mind. You can add partitions later, but that changes which partition each key maps to.

Rebalancing. When a consumer joins, leaves or crashes, Kafka shares the partitions out again among the group. During a rebalance, reading can pause for a short time. Modern Kafka offers a smoother "cooperative" rebalancing.

Committing offsets. Consumers periodically commit (save) their offset back to Kafka (stored in an internal topic). When you commit decides your delivery guarantee:

  • commit before processing → possible loss if you crash,
  • commit after processing → possible duplicates if you crash.

(Lesson 37 covers this in depth.)

Consumer lag is how far behind the newest event a consumer is. It is the most important Kafka metric to watch. Rising lag means consumers cannot keep up: scale them, fix slow processing, or check for errors.

Retention and log compaction

Retention means how long data is kept. Kafka keeps events after they are read. You choose how long:

  • Time-based retention: keep 7 days (a common default), 30 days, or forever.
  • Size-based retention: keep up to X GB per partition.
  • Log compaction: keep only the latest event for each key, and discard older ones for that key.
  1. Offset 10
    user42 → {city: Pune}
  2. Offset 11
    user7 → {…}
  3. Offset 12
    user42 → {city: Mumbai}
  4. Offset 13
    user42 → {city: Delhi}
  5. After compaction
    user7 → {…} and user42 → {city: Delhi}
Log compaction keeps only the latest value per key — a replayable table of current state. · timeline

Compaction turns a topic into a replayable table of current state. It is great for things like "current profile of every user" or "current price of every product". A new service can read the whole compacted topic to build its own copy of that data.

Why Kafka is so fast

  • Sequential disk I/O. Sequential means in order, one after another. Appending to a log and reading it in order are both very fast on disks (lesson 10).
  • The operating system's page cache. This is memory that the operating system uses to keep recent file data. Recent data is usually served from memory without extra work from Kafka.
  • Zero-copy transfer. Data goes from the disk cache straight to the network connection without being copied through the application.
  • Batching and compression everywhere.
  • Partitioning spreads load across many brokers and disks.

The Kafka ecosystem

  • Kafka Connect: a tool with ready-made connectors to move data into Kafka (from databases via CDC (change data capture, which reads the database's change log) tools like Debezium, from files and APIs) and out to other systems (Elasticsearch, S3, data warehouses).
  • Schema Registry: stores Avro, Protobuf or JSON schemas for events and enforces compatible changes, much like the Protobuf rules in lesson 31. A schema is a description of the fields in an event.
  • Kafka Streams / ksqlDB: process streams inside your app (filter, join, aggregate) while keeping state (remembered data) locally.
  • Apache Flink: a powerful, separate stream-processing engine commonly paired with Kafka.
  • Managed Kafka: Confluent Cloud, Amazon MSK, Aiven, and Kafka-compatible alternatives like Redpanda.

When Kafka is a good fit

  • Event streaming between many services (lesson 39).
  • High-volume data pipelines: clickstreams, logs, metrics, IoT.
  • Change Data Capture: streaming every database change to search, caches and warehouses.
  • Event sourcing and audit logs: keeping the full history of changes. (Event sourcing means storing every change as an event instead of only the latest state.)
  • Stream processing: real-time analytics, fraud detection, alerting.

Trade-offs

  • ✅ Very high throughput, durable retention, replay, per-key ordering and many independent consumers.
  • ✅ Decouples producers from consumers across the whole company.
  • ❌ Operational complexity: partitions, replication, rebalancing, disk and monitoring (managed services help a lot).
  • ❌ Not a job queue. No per-message acknowledgement, no built-in delayed messages or per-message retries. A single failing ("poison") message can block its partition. You must build retry topics and DLQs (dead-letter queues, where failed messages are parked; lesson 38).
  • ❌ Partition count is a long-term decision. It limits parallelism, and changing it reshuffles keys.
  • ❌ Latency: it is usually low (milliseconds), but batching gives up a little latency to gain throughput.

When not to use Kafka: a small app with a few background jobs (use SQS, RabbitMQ, or a Redis-based job queue), request/response communication (use HTTP or gRPC), or when your team cannot run it and there is no managed option.

In the Real World

LinkedIn. Kafka was created at LinkedIn around 2010 by Jay Kreps, Neha Narkhede and Jun Rao, to move activity data and system metrics between systems. It was released as open source and became an Apache project. LinkedIn has publicly described handling trillions of messages per day with Kafka. Jay Kreps' essay "The Log" explains the thinking behind it and is one of the most influential pieces of writing on data systems.

Uber uses Kafka as a central pipeline for trip events, driver locations, logs and more, and has written about building reliable retry and dead-letter handling on top of it (lesson 38).

Netflix uses Kafka in its data pipeline to move huge volumes of events (like playback and app activity) to real-time processing and analytics systems.

The New York Times described storing every piece of content it has ever published in a Kafka topic, and using it as the source of truth (the main, trusted copy) to feed its search and content services. It is a good example of Kafka as a replayable history, not just a message bus.

Change Data Capture. Many companies use Debezium + Kafka Connect to stream every change in their PostgreSQL or MySQL databases into Kafka. Search indexes, caches and data warehouses then stay in sync automatically, without the dual-write problems (writing to two systems and one write failing) described in lesson 19.

Interview Questions

Q1How is Kafka different from a traditional message queue?

Kafka is a durable, partitioned log. Messages are not deleted when read. They are kept by time, size or compaction, and each consumer group tracks its own offset. This allows replay, many independent consumers and very high throughput. But there is no built-in per-message acknowledgement, delay or retry.

Q2How does Kafka guarantee ordering?

Only within a partition. Producers send events with a key, and all events with the same key hash to the same partition, so each key's events are read in order. There is no ordering across partitions.

Q3What limits consumer parallelism in Kafka?

The partition count. Within a group each partition is consumed by at most one member, so consumers beyond the number of partitions sit idle. Adding partitions later changes the key-to-partition mapping.

Q4What is consumer lag, and why watch it?

The difference between the latest offset in a partition and the consumer group's committed offset — how far behind processing is. Rising lag means consumers cannot keep up. Add consumers, speed up processing, or look for a stuck poison message (a bad message that always fails).

Q5How do you make Kafka writes durable?

Replication factor 3, producers with acks=all, min.insync.replicas=2, and the idempotent producer enabled. A write is acknowledged only when at least two in-sync replicas have it, and a leader failover cannot lose it.

Q6What is log compaction used for?

It keeps only the latest record for each key, so a topic becomes a replayable snapshot of current state, for example every user's current profile. New services bootstrap by reading the compacted topic from the start.

Key Takeaways

  • Kafka is a distributed, append-only log. Events are kept, and consumers track their own offsets, which enables replay.
  • Topics are split into partitions. The key decides the partition, and order is guaranteed within a partition.
  • Partitions are replicated. Use acks=all + min.insync.replicas for important data.
  • Consumer groups share partitions (one consumer per partition per group). Partitions limit parallelism, and consumer lag is the key metric.
  • Retention and log compaction make Kafka both a message bus and a replayable history. It is powerful, but not a simple job queue.

Further Reading

  • The official Apache Kafka documentation (the "Introduction", "Design" and "Implementation" sections)
  • Jay Kreps' essay "The Log: What every software engineer should know about real-time data's unifying abstraction"
  • The paper "Kafka: a Distributed Messaging System for Log Processing" (NetDB 2011)
  • Kafka: The Definitive Guide (2nd edition) by Gwen Shapira, Todd Palino, Rajini Sivaram and Krit Petty
  • Designing Data-Intensive Applications by Martin Kleppmann (chapter 11, "Stream Processing")
  • LinkedIn's engineering blog posts on running Kafka at scale

Published by Jainik · Last updated · How these lessons are made

Keep learning

Related series