Reference Search docs

Schema & migrations

Default durable journal schema lives in SQLite storage engine. Engines may differ physically; semantics (stream heads, positions, fencing, staged effects) must pass conformance.

Versioning

ConstantMeaning
SCHEMA_VERSIONCurrent (v2)
LEGACY_SCHEMA_VERSIONPrior on-disk (v1)

PRAGMA user_version must match code. Opening a newer DB with older code → UNSUPPORTED_SCHEMA_VERSION (fail closed).

Core tables (v2 conceptual)

TableRole
streamsHead row: stream id, revision, owner_epoch, metadata
eventsAppend-only bodies + per-stream seq + store position
effects / staged workQueue, timer, outbox, signals pending dispatch
subscriptions / checkpointsDurable consumer positions
snapshotsOptional fold caches (never source of truth)

Exact SQL is owned by the storage engine; do not re-implement in apps.

Native pragmas

Native single-owner partitions use WAL-friendly settings with synchronous=FULL (or equivalent durability) — throughput second to crash safety for the default path.

Codecs

Event payloads encode via versioned codecs. Unknown codec → UNSUPPORTED_CODEC. Upcasters live in the data plane, not as silent rewrite of historical bytes without policy.

Migration rules

  1. Forward-only migrations; no destructive “fix by deleting the file” in production paths.
  2. Legacy streams get owner_epoch = 0 until first fenced write.
  3. Integrity checks: contiguous seq, head matches last event, positions monotonic — failures → STREAM_INTEGRITY / MIGRATION_FAILURE.
  4. Tests: Migration fixtures.

What apps must not do

  • Open the SQLite file and invent tables beside the journal.
  • Use COUNT(*) as stream revision.
  • Multi-writer mount the same file over NFS/SMB and call it HA.

EventStore · Durability testing · WIT storage