Skip to content

Architecture

xcon-db is an HTAP engine: the write path and the read path are different machines that share one directory.

Write path

A write (INSERT, ILP line, tombstone) is:

  1. encoded as a RowDelta(table, entity, ts) plus whichever channels actually arrived,
  2. appended to the delta log and fsync'ed (group commit) — then acked,
  3. added to the memtable, the in-memory image of the same rows, split per channel.

The delta log is the WAL. There is no second journal; see Durability.

Generations

Each delta log file is bound to the memtable holding exactly its rows — together they form a generation. A merge freezes the active generation as a unit and opens a fresh one, so the worker always knows precisely which log files its output covers.

The bridge: merge worker

A background worker folds frozen generations into columnar segments (per channel, per day-partition), triggered by size (-merge-bytes) or time (-merge-every), throttled (-merge-throttle) so compression never starves foreground ingest on a small VPS. Once every covered segment is durable, the old log files are deleted.

Read path

Segments are immutable, compressed, mmap'ed columnar files with sparse indexes — the OS page cache is the only cache. Every read combines the columnar segments with the unmerged memtables (active and frozen). Skipping either side would lose the last seconds of writes; this is a correctness rule, not a tuning choice.

What is deliberately absent

  • No Raft, no config servers, no auto-rebalancing — scale is firm→node routing, done by you
  • No buffer pool — mmap + page cache
  • No general SQL optimizer or joins — a time-series subset executes; everything else is politely refused