Glossary
Terms as Celeriant uses them, each linked to the page that explains it.
Aggregate
One independent event stream, addressed by an aggregate key. Events inside it are strictly ordered with no gaps. The unit of ordering, of optimistic concurrency and of reads. There is no order across aggregates. See The aggregate hierarchy.
Aggregate key
The three-part address org_id / aggregate_type_id / aggregate_id. All three parts are 128-bit ids, so a UUID fits in each. See The aggregate hierarchy.
Org
The first part of the aggregate key: the top-level tenant. Schemas, listings and routing can all be scoped by it. See The aggregate hierarchy.
Aggregate type
The second part of the aggregate key, grouping aggregates of the same kind (Orders, Accounts). Schemas are registered against an org and aggregate type. See The aggregate hierarchy.
Aggregate id
The third part of the aggregate key, naming one stream. Under the default aggregate_id routing rule it also decides the shard. See The aggregate hierarchy.
Event
An immutable fact appended to an aggregate. Carries a payload (opaque bytes to the server unless a schema is registered), an event type, a client event timestamp, an optional client event id, a client seq, a server-assigned event seq, and an IV if encrypted. Its batch adds the server timestamp and writer. See Events and the append-only log.
Event type
A (major, minor) pair of numbers on each event. Major for a breaking change to the payload shape, minor for a compatible one. There is no event-type name; the aggregate type plus the pair is the whole identity, and it is what a schema is keyed to. See Events and the append-only log.
Event batch
The events one write appends to one aggregate, stored together. One batch per aggregate per write, with one aggregate version, one client id and one server timestamp. See Events and the append-only log.
Aggregate version
The index of an aggregate's latest batch. Starts at 1 with the first write and goes up by one per batch, not per event. A missing aggregate is at version 0. Reads take a starting version and page by it; a watch notification reports a version range. The same number is called the batch index. Not related to the event type's (major, minor). See Reads and ordering.
Batch index
Another name for aggregate version, used when talking about position in the stream rather than concurrency.
Event seq
The server-assigned per-event index inside an aggregate: 1, 2, 3 across all batches. A batch of three events at version 4 might carry event seqs 7, 8 and 9. Reads and OCC work on the aggregate version; event seq numbers individual events. See Events and the append-only log.
Expected version
The aggregate version a conditional write requires. The write lands only if the aggregate is at exactly that version; otherwise it fails with OptimisticConcurrencyViolation (2003) and nothing is appended. Expected version 0 means "only if the aggregate does not exist yet". Omit it for an unconditional append. See Optimistic concurrency.
Optimistic concurrency
Appending only if the aggregate is still at the version you read, via expected version. On conflict you re-read, re-decide, and write again. Kafka has no equivalent. See Optimistic concurrency.
Client id
A 128-bit id naming the writer. Every write, delete, trim and schema registration carries one. Either you pick it (a stable UUID per service), or the server derives it from the public key the client proves at the identity handshake. It grants no permissions; that is the API key's job. See Identity and authentication.
Client seq
A writer-assigned sequence number on each event. With enforceClientIdempotency on, the server keeps the highest client seq per (aggregate, client id) and rejects a write whose lowest client seq is at or below it with ClientIdempotencyViolation (2002). For a writer that owns its client id alone that means "already landed"; under a shared client id, verify whose event holds the seq first. See Idempotent retries.
User id
An optional 128-bit id a write can carry to record which end user it acted for. Stored with the batch. See Request and response.
Correlation id
An optional 128-bit id on a request, echoed on its response, for tracing. See Request and response.
Shard
A slice of the keyspace owned by one core, with its own write-ahead log. Shard count defaults to the CPU count (--num-shards). It is saved to server_meta.toml on first start; a restart with a different count refuses to start. Ordering, atomic multi-aggregate writes and watches all live inside one shard. See Consistency boundaries.
Routing rule
Which part of the aggregate key picks the shard: org_id, aggregate_type_id or aggregate_id (the default), set by --routing-rule. Placement is id % shard_count, a plain modulo, so you control co-location through the ids you choose. Like the shard count, it is saved on first start and cannot change afterwards. See The aggregate hierarchy.
Consistency boundary
The set of aggregates one write commits atomically. In Celeriant that is any set of aggregates on one shard. A write whose targets span shards fails with ShardRoutingMultipleShards (9001). See Consistency boundaries.
wal_seq
The position of an entry in a shard's write-ahead log. Every entry gets one: an event batch, a delete, a trim, a schema registration. Monotonic per shard, meaningless across shards. Clients order by aggregate version, not wal_seq. See The aggregate hierarchy.
Tip hash
The running BLAKE3 hash at the end of a shard's log. Each new WAL entry stores the previous tip hash, and the new tip is the hash of that entry chained onto the old tip. Replication uses it to detect a forked log. See The audit chain.
Audit chain
The BLAKE3 hash chain formed by tip hashes across a shard's log entries. The chain runs per shard, not per aggregate. Rewrite a past entry and every later hash stops matching. It makes tampering detectable, not impossible, and it does not say who did it. See The audit chain.
Trim
TrimStart drops the head of an aggregate: everything before KeepFromAggregateVersion becomes unreadable. Logical at once, physical after compaction. See Retention and deletion.
Trim floor
The lowest aggregate version still readable after trims. Reads start at it. It only moves forward. See Retention and deletion.
Delete
Removes a whole aggregate, guarded by expected version like a write. AllowRecreate decides whether the key can be written again; AllowSequenceContinuation decides whether a recreated aggregate continues its old version and event seq numbering or restarts at 1. See Retention and deletion.
Compaction
Background rewrite of log segments that physically drops trimmed and deleted events. Until it runs, those bytes are unreadable but still on disk. See Retention and deletion.
Schema
A JSON Schema, Avro or Protobuf definition registered for (org, aggregate type, major, minor). The server validates every unencrypted event of that type on write and rejects a non-conforming one with WriteSchemaValidationFailed (2022). Additive only: no update or delete. See Schema validation and Schema formats.
Encryption
Client-side, per event. The server stores the opaque payload plus an optional 12-byte IV (documented as an AES-GCM IV, never checked) and never sees a key; no client library ships an encrypt helper. Encrypted events skip schema validation. See Encryption.
Watch
A subscription to change notifications, scoped by org, aggregate type, or aggregate, which must fit the routing rule. A notification names the aggregate, the operation (write, delete, trim, create) and the version range; you read the events yourself. The requested latency is a coalescing window capped by --max-requested-latency-ms (default 2000). See Watch and subscribe.
Projection
A read model built by folding events into a query store such as Postgres. Celeriant is the write side; projections live outside it. See Building a read model.
Leader / follower
The two roles in a cluster. The leader takes writes and replicates each batch to the follower; both fdatasync it before the leader acknowledges. The follower can serve reads when a client opts in to follower routing. A single node with no cluster runs as standalone. See Two-node cluster.
Lease
The right to be leader, held in one S3 object (cluster/lease.json) and taken with a conditional PUT on its etag. While heartbeats succeed the leader never touches S3; the follower takes the lease only after heartbeats stop and the heartbeat lease (--heartbeat-lease-duration-ms, default 1500) expires. See Leader election and S3 leases.
Lease epoch
A counter in the lease that goes up each time leadership is taken. Every WAL entry records the epoch it was written under. The monotonic epoch is what stops an ABA race on the lease object. See Leader election and S3 leases.
S3 fallback
When the follower is unreachable, the leader writes each batch to S3 before acknowledging, so an acked write still exists in two places. Write latency rises by the S3 round trip until the follower returns. See Durability and safety.
Fsync window
How long a shard waits to gather concurrent writes into one fdatasync (--fsync-delay-us, default 4000). An idle shard skips it. Under load it sets the latency floor. The replication window (--replication-delay-us) does the same for replication sends. See Performance.