Producers, brokers, consumers, topics, partitions, and offsets: the Kafka / Kinesis / Pub-Sub mental model.
⏱ 18 min readTopics chapter readerLevel · Streaming & Real-Time
01 · Orientation
What You'll Master Here
producers append events, the log keeps them durable and ordered, consumers read forward at their own pace.
⏱ 5 min · Topic 1 of 7
This chapter opens the streaming half of the course. Everything so far could be done in batch; from here on the data never ends. Streaming architecture is how you move and process an endless flow of events the instant they happen, and it has its own vocabulary, its own components, and its own ways of failing.
The good news is that the whole architecture rests on one beautifully simple idea: the log. A streaming platform like Kafka is, at heart, an append-only log that producers write to and consumers read from. Once you understand the log, topics, partitions, offsets, and consumer groups all fall out of it naturally.
By the end you will be able to draw the producer → broker → consumer architecture, explain why partitions are the key to both scale and ordering, and reason about offsets and consumer groups, the machinery LinkedIn invented Kafka to provide and that now moves trillions of messages a day across the industry.
Core mental model
A streaming platform is an append-only log in the middle: producers append events, the log keeps them durable and ordered, consumers read forward at their own pace.
Why it matters
Streaming is how real-time decisions get made: fraud blocks, surge pricing, live recommendations. The log-based architecture in this chapter is the foundation under all of it, and it is the model nearly every streaming system (Kafka, Kinesis, Pub/Sub) shares.
event
An immutable record that something happened (a click, a payment) at a point in time.
broker / log
The durable, append-only store in the middle that holds events between producers and consumers.
producer
A program that appends events to the log.
consumer
A program that reads events from the log and acts on them.
Six statements · which are true of a log?A log is not a queue with better marketing. Three of these six are true of one and not the other.0 marked true
Common mistake
Picturing streaming as "a fast database" rather than a log. You misunderstand ordering, replay, and consumer offsets, which only make sense in the log model.
Better habit
Think in terms of an append-only log, not a queue you drain.
Separate producers, the broker, and consumers in your mental model.
Remember events are immutable facts, never updated in place.
The big idea
A stream is a log: an ordered, append-only sequence of immutable events. Producers write to the end, consumers read forward and remember their position. Everything else is detail on top of this.
How to study this chapter
Start with the log and the three roles, then partitions (the heart of scale and order), then offsets and consumer groups. Each builds on the last.
Remember this
Streaming architecture is an append-only log with producers, a broker, and consumers; master the log and topics, partitions, offsets, and consumer groups all follow.
Practice2 prompts
Define producer, broker, and consumer in one sentence each.
Explain why an event is immutable.
02 · The foundation
The Log: Producers, Broker, Consumers
The log is a shared, durable timeline of events. Writing appends to the end; reading is just remembering your position. Nobody’s read removes anyone else’s data.
⏱ 4 min · Topic 2 of 7
At the centre of every streaming platform is a log: an ordered, append-only sequence of events. Producers append new events to the end; the broker stores them durably; consumers read forward from wherever they left off. Crucially, reading does not delete, unlike a traditional queue, the log retains events so many consumers can read the same stream independently, and any of them can rewind and replay.
This design is what makes streaming so powerful. One producer (the orders service) can feed many consumers at once: a fraud detector, a warehouse loader, a real-time dashboard, all reading the same log at their own pace. Add a new consumer next year and it can replay history from the start. The log decouples who produces data from who uses it.
A topic is just a named log for one kind of event (an "orders" topic, a "clicks" topic). Producers write to a topic; consumers subscribe to it. This is the producer → broker(topic) → consumer picture, the irreducible core of Kafka, Kinesis, and Pub/Sub alike.
Core mental model
The log is a shared, durable timeline of events. Writing appends to the end; reading is just remembering your position. Nobody’s read removes anyone else’s data.
Why it matters
The retain-and-replay log is the property that separates streaming platforms from simple message queues. It is what enables multiple independent consumers, replay after bugs, and the event-driven architectures that modern companies run on.
log (append-only)
An ordered sequence where events are only ever added to the end, never changed.
topic
A named log for one category of events (orders, clicks, payments).
retention
How long the broker keeps events; reads do not delete them.
replay
Re-reading the log from an earlier position, e.g. to reprocess with new logic.
Common mistake
Treating a topic like a queue that empties when read. You assume one consumer "takes" a message, missing that many consumers and replay are the whole point.
Better habit
Design for multiple independent consumers of the same topic.
Lean on retention and replay to reprocess after bugs.
Model each event category as its own topic.
Production reality
At LinkedIn, a single "member activity" topic feeds dozens of consumers, search indexing, feed ranking, analytics, all reading the same durable log. That fan-out, from one producer to many consumers, is why Kafka exists.
Remember this
A streaming platform is a durable, replayable log organised into topics; reads do not delete, so many consumers can independently read and replay the same events.
Practice2 prompts
Explain how a log differs from a queue that empties on read.
Give an example of one topic feeding three different consumers.
03 · The heart
Partitions: Scale and Ordering
A topic is many parallel logs (partitions). Order is guaranteed within a partition, never across. The partition key decides what stays ordered together.
⏱ 6 min · Topic 3 of 7
A single log on one machine would cap your throughput and storage. So a topic is split into partitions, each an independent ordered log, and they can live on different machines. Partitions are the single most important concept in streaming, because they provide two things at once: parallelism and ordering.
Parallelism: with three partitions, three consumers can read in parallel, tripling throughput. Ordering: events are ordered within a partition, but not across partitions. This is the key trade-off. If you need all of one customer’s events in order, you must send them to the same partition, usually by hashing a key (customer_id) so the same key always lands on the same partition.
The example shows the consequence. Events with key "u1" all go to partition 0 and stay perfectly ordered; "u2" goes to partition 1. Across partitions there is no global order, partition 0 and partition 1 interleave however the consumers happen to read them. Choosing the partition key is therefore choosing your ordering guarantee.
Core mental model
A topic is many parallel logs (partitions). Order is guaranteed within a partition, never across. The partition key decides what stays ordered together.
Why it matters
Partitions are where streaming scale and correctness meet. Get the partition key right and related events stay ordered while the system scales out; get it wrong and you either lose ordering or create a hot partition that bottlenecks everything.
partition
One independent ordered log within a topic; the unit of parallelism and ordering.
partition key
The value hashed to choose a partition; same key → same partition → ordered together.
per-partition ordering
Events are ordered within a partition but not across partitions.
hot partition
A partition receiving disproportionate traffic (a skewed key), bottlenecking the topic.
One topic · the decision you cannot easily undoThe key and the count decide distribution, ordering and your consumer ceiling — all three at once.max 12 useful consumers
Partition key
Partitions
what the choice decides
here
distribution
even across all 12
ordering you get
per order — the guarantee most designs actually need
useful consumers in a group
12
adding partitions later
changes which partition a key lands in — ordering breaks across the change
Even distribution, per-order ordering, and 12 consumers of headroomThe count is a ceiling on consumers and the key is the ordering guarantee. Neither can be changed later without consequences, which is why this is the decision to spend five minutes on rather than accept the default of one.
Partition key controls orderingworked example
SQL
Input data
events (key, value) → partition5 rows
key
event
partition
u1
login
p0
u2
login
p1
u1
purchase
p0
u1
logout
p0
u2
logout
p1
All u1 events land on p0 and stay in order (login → purchase → logout). u2 events are ordered on p1. There is no global order across p0 and p1.
-- Producer hashes the key to pick a partition:-- partition = hash(key) % num_partitions-- Same key -> same partition -> guaranteed order for that key.
Keying by user_id keeps each user’s events ordered on one partition, while different users spread across partitions for parallelism. Ordering is per-key, not global.
Common mistake
Assuming a topic gives global ordering across all events. Cross-partition events arrive interleaved; logic that expects total order produces wrong results.
Choosing a partition key that concentrates traffic (e.g. country = US). One hot partition bottlenecks the topic while others sit idle, capping throughput.
Better habit
Pick a partition key that keeps related events ordered (e.g. user_id).
Choose a key with even distribution to avoid hot partitions.
Remember ordering is per-partition; design logic accordingly.
Interview note
A favourite question: "does Kafka guarantee ordering?" The precise answer is "within a partition, yes; across partitions, no, so you key related events to the same partition." That nuance is the signal.
Remember this
Partitions give streaming both parallelism and per-partition ordering; the partition key decides which events stay ordered together, and a skewed key creates a throughput-killing hot partition.
Practice2 prompts
Explain why Kafka guarantees order within but not across partitions.
Choose a partition key for per-user ordering and explain the trade-off.
04 · Reading
Offsets & Consumer Groups
An offset is a per-partition bookmark each consumer commits. A consumer group shares a topic’s partitions among its members; different groups read the same topic independently.
⏱ 6 min · Topic 4 of 7
Because the log is not consumed by reading, each consumer must remember how far it has read. That bookmark is the offset: a per-partition position. A consumer commits its offset as it processes, so after a restart it resumes from there rather than re-reading everything or skipping ahead. Offsets are why consumers can crash and recover cleanly.
To scale consumption, related consumers form a consumer group. The group shares the work: each partition is assigned to exactly one consumer in the group, so with three partitions and three consumers, each handles one. Add a fourth consumer and it sits idle (no partition to take); drop to two and one consumer takes two partitions. This automatic rebalancing is how streaming consumers scale horizontally.
Two different applications (a fraud service and an analytics loader) use two different consumer groups, and each group independently tracks its own offsets on the same topic. This is the final piece: one durable log, partitioned for scale and order, read by multiple groups that each remember their own position. That is the whole architecture.
Core mental model
An offset is a per-partition bookmark each consumer commits. A consumer group shares a topic’s partitions among its members; different groups read the same topic independently.
Why it matters
Offsets and consumer groups are how streaming achieves fault tolerance and horizontal scale. Misunderstand offset commits and you get duplicate or lost processing; misunderstand groups and you cannot reason about how consumption scales.
offset
A consumer’s position in a partition; committed so it can resume after a restart.
consumer group
A set of consumers that share a topic’s partitions, one partition per consumer.
rebalancing
Reassigning partitions among group members when consumers join or leave.
offset commit timing
When a consumer records progress; commit-before-process risks loss, commit-after risks duplicates.
6 partitions · one consumer groupConsumers come and go. The assignment moves, and so does whatever was half-finished.all busy
Consumers in the group
Offsets committed
Assignment
consumer 12 partitions
consumer 22 partitions
consumer 32 partitions
Every consumer has workPartitions divide as evenly as they can. Adding a consumer triggers a rebalance, which is where the next question matters.
What the rebalance does to work in flightA partition is revoked from one consumer and given to another. Anything processed since the last commit is processed again by the new owner — so a rebalance is a duplicate-delivery event, and a consumer that is not idempotent will double-count every time somebody deploys.
When you commit the offset decides your delivery guaranteeworked example
The only difference is the order of two lines, yet it flips the delivery semantics. Commit-after-process means a crash replays the event (at-least-once) — safe when processing is idempotent. Commit-before-process means a crash silently skips it (at-most-once). This is the Chapter 11 delivery-semantics trade-off made concrete.
Common mistake
Committing the offset before the work is actually done. A crash after commit but before processing loses those events; commit after processing instead.
Adding more consumers than partitions to "go faster". Extra consumers sit idle; partition count, not consumer count, caps parallelism.
Better habit
Commit offsets after processing, and make processing idempotent.
Size partition count to the parallelism you want from a group.
Use separate consumer groups for independent applications.
The offset-commit trap
Commit-after-process gives at-least-once (a crash may reprocess) and is the safe default with idempotent consumers. Commit-before-process gives at-most-once and can silently lose events. The choice is exactly the delivery-semantics trade-off from Chapter 11.
Interview note
Explaining that "parallelism is capped by partition count, and extra consumers in a group idle" shows real Kafka understanding, it is a very common point of confusion.
Remember this
Consumers track per-partition offsets and form groups that share partitions for scale; commit offsets after processing, and remember partition count caps a group’s parallelism.
Practice2 prompts
Explain what happens if you commit offsets before processing and then crash.
You have 4 partitions and 6 consumers in one group, how many are idle?
05 · Made real
Producing and Consuming, For Real
A send is not done when your code returns — it is done when as many replicas as you demanded have written it to disk.
⏱ 8 min · Topic 5 of 7
Every streaming tutorial shows three lines that send a message. None of them shows the settings that decide whether that message still exists after a broker restarts.
The dial below is the one that matters most: what your producer waited for before it told you the write succeeded. Then the consumer side, and the same thing on Kinesis.
Core mental model
A send is not done when your code returns — it is done when as many replicas as you demanded have written it to disk.
Why it matters
A producer with default settings can report success for records that are never stored. Nothing errors, nothing alerts, and the gap only appears when a broker dies.
in-sync replica (ISR)
A follower that has caught up with the leader. acks=all waits for all of them, and min.insync.replicas sets how many must exist for a write to be allowed at all.
idempotent producer
The broker deduplicates producer retries using a sequence number, so a retried send cannot append a second copy.
consumer lag
How many records sit between a consumer’s committed offset and the end of the partition. The single most useful streaming metric.
schema registry
A service holding the schema for each topic and refusing producer changes that would break existing readers.
Marlow checkout → KafkaYour producer returned success. Which of these did that actually mean?acks=1
checkoutPRODUCEREmits one order event.→leaderBROKER 1Writes to its own log.→followerBROKER 2Replicates from the leader.→consumerREADSOnly sees committed records.
The leader has itthroughput — High
The leader wrote the record to its own log and replied. Followers may not have it yet.
survives
loses
A producer crash, a consumer crash, an ordinary retry.
Records acknowledged by a leader that then dies before any follower replicates them.
Acknowledged does not mean durableData can be acknowledged and then vanish, with no error anywhere. Fine for metrics you can lose; wrong for an order.
The producer, configured
from confluent_kafka import Producer
producer = Producer({
"bootstrap.servers": BROKERS,
"acks": "1",
"linger.ms": 20, # batch for 20ms — throughput, at 20ms of latency
"compression.type": "zstd",
})
def on_delivery(err, msg):
if err: # this is the only place you learn it failed
log.error("delivery failed", key=msg.key(), error=err)
producer.produce(
topic="orders",
key=order["order_id"], # same key → same partition → ordered
value=json.dumps(order).encode(),
on_delivery=on_delivery,
)
producer.flush() # block until the queue drains before exit
The consumer, with the commit in the right placeworked example
Auto-commit is the default and it commits on a timer, which means it can acknowledge records you have not finished processing. Turning it off and committing after the work is the single most important consumer setting.
The same job on Kinesisworked example
SQL
importboto3kinesis=boto3.client("kinesis")#--- producing: PutRecords batches up to 500 records per call ---------------kinesis.put_records(StreamName="marlow-orders",Records=[{"Data":json.dumps(o).encode(),"PartitionKey":o["order_id"],#sameroleasaKafkamessagekey}foroinorders],)#NOTE:put_recordsispartiallyfallible—checktheresponse!#failed=[rforrinresp["Records"]ifr.get("ErrorCode")]#andretryonlythose,oryouwillsilentlydroprecords.#--- consuming: iterate a shard ---------------------------------------------it=kinesis.get_shard_iterator(StreamName="marlow-orders",ShardId="shardId-000000000000",ShardIteratorType="AFTER_SEQUENCE_NUMBER",StartingSequenceNumber=load_checkpoint(),)["ShardIterator"]whileit:resp=kinesis.get_records(ShardIterator=it,Limit=1000)handle(resp["Records"])save_checkpoint(resp["Records"][-1]["SequenceNumber"])#afterhandlingit=resp["NextShardIterator"]
Different vocabulary, identical shape: shards instead of partitions, a shard iterator instead of an offset, and a lease table instead of a consumer group. Knowing the mapping means you can read either.
A polled API is not a stream, but it is where many streams start. The producer is the adapter — poll, publish, and let everything downstream be event-driven.
Schemas, so a producer change cannot break every consumerworked example
JSON on a topic means every consumer guesses. A schema registry makes the contract explicit and refuses a producer change that would break readers — the streaming version of Chapter 19’s data contracts.
The same concepts, three brokers
Concept
Kafka
Kinesis
Pub/Sub
Unit of parallelism
Partition
Shard
No shards — the subscription scales itself
Ordering guarantee
Per partition
Per shard
Per ordering key, if you set one
Position marker
Offset (per consumer group)
Sequence number + iterator
Ack id — the service tracks it for you
Group coordination
Consumer group protocol
KCL lease table in DynamoDB
Subscription, server-side
Replay
Seek to any retained offset
Iterator from a timestamp or sequence
Seek to a snapshot or timestamp
Retention
Configurable, can be for ever
Up to 365 days
Up to 31 days
You operate
Brokers, or pay someone to
Nothing — shards are the dial
Nothing
The producer settings that decide whether data survives
Setting
Default
Set it to
Because
acks
1 (leader only)
all
A leader can acknowledge and then die before replicating
enable.idempotence
false (older clients)
true
Otherwise a producer retry appends the record twice
retries
varies
high, with delivery.timeout.ms bounding it
A transient broker blip should not lose a record
linger.ms
0
5–100
Batching multiplies throughput; the cost is that much latency
compression.type
none
zstd or lz4
Network and disk are usually the constraint, not CPU
max.in.flight…
5
keep ≤5 with idempotence on
Above that, a retry can reorder records within a partition
Consumer settings people learn about during an incident
Setting
What goes wrong at the default
enable.auto.commit=true
Offsets advance on a timer, acknowledging records you have not processed
max.poll.interval.ms too low
A slow batch looks like a dead consumer, so the group rebalances mid-work
auto.offset.reset=latest
A new consumer group silently skips everything already in the topic
No consumer.close()
The group waits for the session timeout before rebalancing, so processing stalls
Common mistake
Leaving acks at the default for data you cannot regenerate. Records are acknowledged and then lost when a leader fails, with no error raised anywhere.
Leaving auto-commit on. Offsets advance on a timer, so a crash skips records the consumer never actually processed.
Ignoring the partial-failure response from a batch put. Kinesis put_records returns per-record errors; unchecked, a portion of every batch is silently dropped.
Putting raw JSON on a topic with no schema. A producer adds a field, a consumer parses strictly, and the failure appears in someone else’s service.
Better habit
Set acks and idempotence explicitly, and write down why.
Commit offsets after the work, never on a timer.
Alert on consumer lag before you alert on anything else.
Put a schema on the topic while it still has one consumer.
The default is throughput, not safety
Client defaults are tuned to look fast in a benchmark. Every setting in the table above trades a little throughput for the property you actually wanted, and none of them is on by default.
The follow-up you will actually get
"Your producer got a success response and the record is not in the topic — how?" Answer with acks=1, a leader acknowledging, and the leader dying before a follower replicated. Then say what you would set instead.
Remember this
A stream is only as durable as the acknowledgement your producer waited for and as correct as the moment your consumer commits — both are settings, and both default to fast rather than safe.
Practice2 prompts
Find the acks setting of a producer in your stack and say what it means for a leader failure.
For a consumer you run, name the line where a crash would skip records.
06 · Practice
Practice Lab
Ordering is per-partition. The partition key decides what is ordered and what is spread, and it is effectively permanent.
⏱ 3 min · Topic 6 of 7
Five scenarios built on the log: partitions, consumer groups, and the two things that break both — a hot key and consumers who want different answers.
Build them on the pipeline canvas with the chapter closed. Each is graded against the scenario’s own requirement rules rather than against a model answer, so there is more than one design that passes — and a design that does not pass is told exactly which requirement it missed.
Core mental model
Ordering is per-partition. The partition key decides what is ordered and what is spread, and it is effectively permanent.
Why it matters
Kafka, Kinesis and Pub/Sub are the same object with different billing. Everything mysterious about streaming falls out of the log, its partitions and the offsets consumers keep — and these scenarios make you use all three.
Common mistake
Choosing a partition key for ordering without checking its distribution, and creating a hot partition. The review will find it, but only after you have submitted a design you believed in — which is the point. That is the memory that survives interview pressure.
Revealing the reference design before your own review comes back. You see what correct looks like without finding out what your version got wrong, and your version is the one you will draw again under pressure.
Better habit
For every stream, say out loud what one partition contains and what that guarantees. If the answer is "everything", ordering is fine and throughput is not.
Run the review, fix what it finds, and run it again. The second score is the one that means something.
Narrate the finished design out loud in ninety seconds. If you cannot, the design has a hole you have not found yet.
The last one is the key decision, arriving as an outage
“One tenant ate the cluster” is the partitioning decision from earlier in the chapter, showing up months later as an availability incident.
These are the round, not a warm-up
Five graded design scenarios, each with staged requirement checks and interview probes of its own. Working them out loud, against a clock, is the closest rehearsal to the real thing this module offers.
Remember this
A chapter read is a chapter you can recognise; a scenario built and reviewed is one you can use. Close this and go build.
Practice2 prompts
Before opening any scenario, write down the freshness requirement and who consumes the output.
After each review, write one sentence naming the requirement you missed and why you missed it.
07 · Next Chapter
Next Chapter
You now understand the streaming architecture: a partitioned, replayable log read by consumer groups tracking offsets. The next chapter is what those consumers actually do with the endless flow: process it.
⏱ 3 min · Topic 7 of 7
Next chapter
Stream Processing
You now understand the streaming architecture: a partitioned, replayable log read by consumer groups tracking offsets. The next chapter is what those consumers actually do with the endless flow: process it.
Chapter 14 covers stream processing: windowing an endless stream, event time versus processing time, watermarks, and the stateful operations behind Flink, Spark Structured Streaming, and Kafka Streams.