Suppose a reservation system writes three records for the same seat: reserved, cancelled, reserved. Read in that order, the seat ends occupied. Move the cancellation to the end and it does not. These are invented records, but they show why a log needs more than a bag of facts. Its sequence is part of the meaning of the data.
“Append-only” sounds like a strong promise. New records go at the end; old ones stay put. The phrase deserves a second question: the end of which log? In a large system, there may be many ends, each with its own reader and its own point of progress. A record's position settles some disputes and leaves others open.
An address for each record
The original Kafka paper describes a topic divided into partitions, each a logical log built from segment files. A producer appends to a partition; a consumer reads that partition sequentially from a position called an offset. The paper explicitly says that delivery order is guaranteed within one partition, while messages from different partitions have no shared delivery order. That is a design choice that permits parallel work, not a footnote to be discovered after an incident.
Kafka's later versioned introduction makes the practical rule clear. Events with the same key, such as a reservation identifier, go to the same partition, where readers encounter them in write order. The key makes the reservation's small history travel together. It does not make every reservation in the topic part of one universal queue. Two seats keyed separately can be processed in parallel; neither partition's offset provides a place to insert its records into the other's sequence.
That distinction belongs in the data model. If the example's three records refer to one reservation, giving them the same partition key lets a reducer apply them in log order. If a later rule says that two reservations must never claim the same physical seat, ordering each reservation separately is insufficient by itself. The rule needs a coordination boundary that covers the shared seat. A tidy series for each customer cannot enforce a constraint between customers on its own.
Even a key's apparent lane can require attention when a service changes shape. Microsoft's Event Hubs guidance, updated in October 2026, warns that adding partitions can change where a hashed key lands. Existing records keep their order in their old partition, while subsequent records for the key may be routed elsewhere. Microsoft's advice is to drain the earlier partitions before expanding when that relative order matters. This is a product-specific warning, and it makes the broader point tangible: an ordering promise includes the routing scheme over time.
Sent first, written second
A producer may know the order in which it tried to send two batches. That does not always settle their final order in the log. In Kafka's version 2.5 producer configuration, the documentation warns that retries with more than one request in flight can reorder batches sent to one partition if the first fails and the second succeeds. It also explains that an idempotent producer can prevent a retry from writing a second copy of the same message, subject to its required settings.
This is a more exact question than “does the log preserve order?” Once records have been accepted into a particular partition, offsets describe their place there. The producer may still need settings and discipline to make that place match the order the application intended. A network timeout adds a different uncertainty: the writer may not know whether a request reached the log before the reply vanished. The Kafka design documentation describes that ambiguity and the possibility of duplicates when a producer resends without idempotence.
For the fictional seat, a duplicate cancelled record might be harmless if cancellation simply sets a state. A duplicate charge card command would be a different matter. Those examples are hypothetical; the log does not inspect a record's business meaning. The writer and the consumer must decide whether repeating an operation is safe, and by what identifier they would recognize the repetition.
A reader's place is another record to keep
The sequence in storage is only half the story. A consumer also has a position: which offset it has finished processing. Kafka's consumer design allows a reader to seek backward and reprocess retained records. That is useful when the code building a search index or summary was wrong. It also makes the point of progress a consequential piece of state.
Consider a worker that reads reserved, sends a confirmation email, then saves its offset. If it crashes after sending but before saving, the replacement may read reserved again and send another email. Reverse the order—save the offset first, then send—and a crash between those actions can lose the email. Kafka's design text lays out this exact class of choice between replay and loss, and describes stronger processing arrangements when outputs and offsets can be committed together. An external email system may not participate in that transaction. The worker needs an application-level way to recognize work already done if duplicate confirmation is unacceptable.
The log has not broken its ordering guarantee in either crash. The same record can be read twice in the same place. “Exactly once” for an effect outside the log asks more than an ordered read: it asks how the effect and the saved position survive failure together. That answer depends on the output system as well as the input log.
How much past remains
There is one last limit to the paper-roll metaphor. Appending new records need not mean keeping every old record forever. Kafka's version 2.5 design documentation describes time or size retention and an optional compaction policy. Compaction can remove an earlier value for a key when a later one supersedes it. Remaining records retain their order and original offsets, but some positions no longer return the former record.
That difference matters to a future reader. If the task is to rebuild the latest state of each reservation, a compacted history may contain enough information. If the task is to explain every cancellation and rebooking, removed records cannot be recovered by rewinding to their old offsets. Time-based retention can erase even more of the beginning. A system that promises a complete audit must arrange to preserve the full history somewhere with a retention policy suited to that promise.
The three invented seat records look simple on a whiteboard. In a working system, their meaning depends on a chain of choices: the key that keeps them together, the producer behavior that places them, the offset a reader saves, and the policy that determines how long each remains available. An append-only log supplies a sequence. Its usefulness comes from saying precisely whose sequence it is, what the reader has done with it, and how far back the record still reaches.
A thought worth keeping?



