Delta Log (WAL)
The write buffer is the write-ahead log — one mechanism, not two.
Framing
u32 payload length | u32 CRC32-C(payload) | payload
Payloads are varint-encoded RowDelta records: table, flags, entity, ts plus the channels that arrived (id, kind, value). A tombstone is a flag bit with no channels.
Group commit
Appenders enqueue frames; a kick flushes the pending batch at once (one write+fsync for all of it), and while that fsync runs the next arrivals pile into the following batch. Batch size self-tunes to fsync latency — there is no fixed window. A whole statement commits together too: AppendBatch writes every frame of a multi-row INSERT and syncs once, so a bulk load pays one fsync, not one per row.
In strict durability Append returns only after its batch is durable; in relaxed it returns once the frame is buffered and the committer fsyncs behind it (see Durability). -group-commit 0 disables the committer and fsyncs inline on every append.
Generations & pruning
Log files are numbered (wal/<seq>.log). Each file pairs with the memtable holding exactly its rows — a generation. A merge:
- freezes the active generation, opens
seq+1, - waits for in-flight appends to land,
- folds the frozen memtable into segments (tmp→rename),
- deletes every log file
≤ seq— only after all covered segments are durable.
Recovery
On open, all surviving logs replay in order into a fresh memtable. Scanning stops at the first torn or CRC-corrupt frame and truncates the file there — the classic crash artifact of a half-written tail. If segments already contain some replayed rows (crash between rename and log delete), the next merge drops exact duplicates: re-merging is idempotent.