Trace Raft terms, elections, AppendEntries, log matching, majority replication, commit index, conflicting suffix replacement, and follower catch-up across an AtlasMart leader change.

Raft Mental Model: Leaders, Terms, Log Replication, Commit Index, and Elections

A Raft leader can contain an entry that is not committed. This lesson makes the distinction observable, then follows the entry through election, current-term commitment, and log repair.

Advanced120–155 minutesRaft log/election labPython 3.13+ · standard libraryVendor-neutral · free/local mandatory pathLast reviewed: August 2026
01

Trace Raft leader election using monotonically increasing terms and majority votes.

02

Distinguish an appended log entry from a committed entry and explain the role of the commit index.

03

Explain log matching, conflicting-suffix replacement, and follower catch-up after a leader change.

04

Reason about what a Raft trace proves and what still depends on persistence, membership, and timing assumptions.

1. The problem: an old leader acknowledged itself, then disappeared

AtlasMart's control plane wants to store set-shard-owner=s1:A. Leader A in term 4 appends the command locally and gets it to only follower B. Before a majority receives the entry, A becomes isolated. If the application equates “it is in the leader log” with “it is committed,” it may act on a value that a later legitimate leader can overwrite.

Raft organizes time into monotonically increasing terms. A server is follower, candidate, or leader for a term. Elections select at most one leader per term under the protocol's voting rules. Client commands become log entries identified by index and term. A leader's commit index marks the highest index known committed; only committed entries are safe to apply to the replicated state machine according to Raft's rules.

2. Election safety depends on log freshness

A candidate requests votes with its term and last-log information. A voter grants at most one vote per term and refuses a candidate whose log is less up-to-date than its own. This restriction is not cosmetic: it helps ensure that a candidate capable of winning cannot be missing already committed entries.

In the lab's term-4 scenario, the old entry exists only on A and B, so it was never on a majority. Nodes C, D, and E form a majority whose logs do not contain it; C can legitimately become leader in term 5. That is safe precisely because the term-4 entry was never committed.

3. AppendEntries is both replication and consistency repair

The leader sends AppendEntries messages containing a previous-log index/term anchor plus new entries. Followers accept new entries only if the preceding history matches. When a follower has a conflicting uncommitted suffix, the leader backs up to the last matching point and replaces the conflict. This produces the log matching property: if two logs contain an entry with the same index and term, their preceding histories match.

State Meaning Do not infer
Entry appended on leader Leader has persisted/recorded a proposal according to its implementation Not necessarily committed
Entry replicated to majority Quorum evidence exists For Raft, commit rules still consider term/current-term details
Commit index advanced Leader knows entries through that index are committed under Raft rules Not that every follower has already applied them
Follower applied index Follower state machine has executed committed entries through that point Not that it is safe to serve every read mode without additional rules

4. AtlasMart lab: uncommitted entry disappears safely

Mandatory lab environment

Python 3.13+ standard library only. The generated lab was verified with Python 3.13.5. No database server, Docker, cloud account, paid feature, credential, firewall change, clock manipulation, process killing, or destructive failure injection is required. All failures and partitions are deterministic in-memory simulations.

Term 4's entry reaches only A and B. After A's failure/partition, C wins term 5 from C, D, and E, appends a different current-term entry to that majority, commits it, then repairs A and B's conflicting uncommitted suffix.

python · AtlasMart deterministic simulation
from copy import deepcopy

nodes = ["A", "B", "C", "D", "E"]
majority = 3
logs = {n: [] for n in nodes}
term = 4
leader = "A"
commit_index = 0

print("TERM 4: A IS LEADER")
entry1 = (4, "set-shard-owner=s1:A")
logs["A"].append(entry1)
logs["B"].append(entry1)  # only one follower receives it
replicated = [n for n in nodes if logs[n] == [entry1]]
print("entry1 replicas:", replicated)
print("present on leader:", entry1 in logs[leader])
print("majority replicated:", len(replicated) >= majority)
print("commit_index:", commit_index, "=> entry1 is NOT committed")

print("\nA FAILS/PARTITIONS; C,D,E CAN ELECT IN TERM 5")
term = 5
leader = "C"
voters = ["C", "D", "E"]
print("votes for C:", voters, "majority:", len(voters) >= majority)

# New leader's empty log is authoritative because the old entry was never committed.
entry2 = (5, "set-shard-owner=s1:C")
for n in ["C", "D", "E"]:
    logs[n] = [entry2]
replicated2 = [n for n in nodes if logs[n] == [entry2]]
if len(replicated2) >= majority:
    commit_index = 1
print("entry2 replicas:", replicated2)
print("commit_index:", commit_index, "=> current-term entry committed")

print("\nFOLLOWER CATCH-UP / LOG REPAIR")
for n in ["A", "B"]:
    # AppendEntries conflict handling replaces the uncommitted conflicting suffix.
    logs[n] = deepcopy(logs[leader])
print("logs:")
for n in nodes:
    print(n, logs[n])
print("all logs agree after catch-up:", len({tuple(v) for v in logs.values()}) == 1)
print("old uncommitted term-4 entry survived?", any(entry1 in v for v in logs.values()))
print("lesson: leader-local presence is not the same as commitment")
Expected evidence

The term-4 entry is present on the old leader but never reaches a majority, so the commit index stays at 0. The term-5 entry reaches C/D/E and commits at index 1. Catch-up replaces the old uncommitted suffix on A and B. This is an intentionally compact teaching trace, not a complete implementation of RequestVote/AppendEntries retries, persistence, snapshots, joint consensus, or client-session semantics.

5. The current-term commit rule closes a subtle safety hole

Raft leaders do not simply count replicas of arbitrary older-term entries and mark those entries committed. A leader advances the commit index by counting a majority for an entry from its current term; earlier entries become committed as part of the prefix once that current-term entry commits. This rule is part of Raft's safety proof across leader changes.

Production implementations also persist the current term, voted-for state, and log before responding in ways assumed by the protocol. If a crash erases a vote or accepted log entry that the algorithm assumes survives restart, the paper proof no longer describes the implementation.

6. Deliberately wrong approach: serve authority from an uncommitted leader suffix

Suppose A sends “I own shard s1” to workers immediately after appending the term-4 entry locally. A then partitions, C legitimately wins term 5, and commits C as owner. Now A and C may both act. The correction is to expose only committed ownership decisions, attach the committed term/epoch to work, and enforce a fencing token at the downstream resource. Consensus decides the authority; fencing stops a delayed former authority from using stale credentials.

7. Production judgment

Observe term, leader changes, commit index, applied index, follower match/next indexes, proposal queueing, fsync latency, snapshot installation, and quorum round-trip latency. Frequent elections often inflate tail latency even when safety remains intact. Network placement matters: a leader far from a majority increases commit latency. Membership changes require Raft's safe configuration-change mechanism rather than manual simultaneous edits.

The next lesson reaches the same fundamental agreement problem from Paxos's vocabulary: proposers, acceptors, ballots, promises, accepted values, quorum intersection, and the exact rule that prevents a higher-ballot proposer from replacing an already chosen value.

Check your understanding

  1. Why is an entry on the leader not automatically committed?
  2. What is a Raft term?
  3. Why can C win after the term-4 entry exists only on A and B?
  4. What does log conflict repair do?
  5. Why are persistent term/vote/log writes part of correctness?
Review the answers

1. The leader may fail before the entry is replicated according to Raft’s majority/term commit rules.

2. A monotonically increasing logical epoch used for elections and for rejecting stale leadership/messages.

3. That entry was not committed on a majority, and C can obtain a majority from C/D/E without violating committed-log safety.

4. It finds the last matching prefix and replaces a follower’s conflicting uncommitted suffix with the leader’s log.

5. The protocol assumes those facts survive crashes; forgetting them can permit votes or histories the safety proof forbids.

References

Foundational claims use primary research where practical. Product documentation is used only as a current implementation example and is not required for the mandatory labs.

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.