jonnify·persistence /echo-persistence/platform/bus-and-persistence/the-commit-lsn-is-the-cursor

Module 13 · Dive 12.1

The commit LSN is the cursor.

The accept tier is fast because it amortizes one fsync over a whole batch; the commit tier is durable because each batch becomes one replicated transaction. They meet at the batch, and the number that transaction produces — the LSN — is published over EchoMQ. So a replica catching up, a consumer reading the feed, and the store proving durability all name their position with the same integer. The caller only chooses how long to wait for it. Enqueue and commit below.

One batch, one LSN, one cursor. Enqueues accumulate in the Champ accept tier (fsync per K). Committing folds the batch into a single Graft transaction — :sync waits for the Tigris-replicated commit — which mints an LSN and publishes it over EchoMQ, advancing every replica’s cursor to the same point.
Champ accept tier in-memory CHAMP + fsync / K 0/4 Graft commit tier batch → 1 transaction head LSN: 0 Tigris (object store) commit/{LSN} · If-None-Match PUBLISH lsn over EchoMQ replica R1 cursor: 0 replica R2 cursor: 0
readout · :async returns the moment the batch is fsync’d locally — fast, with the loss window bounded by the open batch. :sync returns only after the Tigris-replicated commit acks, mints the LSN, and publishes it — binding every replica to the same cursor.
§1

The two tiers meet at the batch

graft.design.md

Champ is the accept tier: state lives in memory and a single fsync is amortized over K records, so enqueues are cheap and the only exposure is the open batch — K is the dial, and it is exactly the loss window in records. echo_graft is the commit tier: each batch rolls up into one Graft transaction, replicated to Tigris as a single LSN behind the conditional-write fence of Module 9. The two tiers join precisely at the batch boundary, and that join is where the durability choice lives, per call. :async returns once the batch is fsync’d locally — the fast path, exposure bounded by the open batch. :sync returns only after the Tigris-replicated commit acknowledges — slower, but durable against the loss of the whole node. Crucially, aligning the commit batch to the consumer’s claim batch makes “enqueue through record” one durable, replicated unit: the same boundary that bounds Champ’s fsync is the boundary that becomes a Graft LSN, so there is no seam between accepting work and durably committing it — only a choice of how long to wait.

§2

One integer, three meanings

graft.design.md · eg.3

The LSN that the commit mints is not kept inside the store; it is published over EchoMQ, and that publication is the whole reason the bus and the floor are one system. Consider what the same integer means in three places. On the store side it is a durability boundary: everything at or below it is committed and replicated to Tigris. On a replica it is a position: a catching-up node fetches the head, learns the LSN, and faults pages up to it (Module 9’s log-head recovery). On the bus it is an offset: a consumer of the change feed subscribes “from this LSN” and receives every advance after it. Because all three are the identical number, a replica’s lag, a consumer’s backlog, and a commit’s durability are measured on one axis, and binding them is free — the commit already did it by publishing. This is also why the cross-runtime contract of Module 10 used the feed cursor as its recovery key: the LSN is the one coordinate every participant, in any runtime, already agrees on. Choose one cursor for both worlds and the rest of the platform’s coherence follows.

§3

References & sources