Skip to content

Core Concepts

This page defines the vocabulary used throughout the rest of the documentation. Read it before diving into the guides.

An entity is a typed record identified by a unique 32-byte ID within an entity kind. ConvergeDB stores only the current state of each entity. There is no history.

Every entity carries:

  • Entity ID: a 32-byte opaque identifier, unique within its kind.
  • Version: a server-assigned number that increases each time the entity’s state changes. Versions are strictly monotonically increasing per entity.
  • Source set: a bitmask (u64) indicating which sources currently assert this entity. When all bits are cleared, the entity is tombstoned.
  • Field data: the entity’s current field values, laid out as a fixed-size byte buffer determined by the schema.

An entity kind is a named collection with a fixed schema of typed fields. Think of it as a table. Kinds must be registered on the server before any entities can be written.

Schemas are persisted on the server and survive restarts. Registering the same schema again is a no-op that returns the existing KindId.

See Defining Entity Kinds for details.

A source is an authenticated writer identity, identified by a number from 0 to 63. Every client connection is assigned a SourceId.

The server tracks which sources assert each entity using a source bitset: a u64 where bit N is set if source N has asserted the entity. This enables clean multi-writer semantics:

  • Multiple sources can assert the same entity independently. Their bits accumulate.
  • Retracting from one source clears only that source’s bit. The entity remains alive as long as any bit is set.
  • If all bits are cleared, the entity is tombstoned.

Assignment rule: Two instances of the same service should use the same SourceId. Two different services should use different SourceIds. There is a maximum of 64 sources. See Limits for details.

ConvergeDB has exactly four operations (plus PATCH as a variant of ASSERT):

OperationPurpose
ASSERTDeclare the full current state of an entity. Creates it if it does not exist. Sets this source’s bit.
PATCHUpdate only specific fields of an entity. Other fields are untouched. Sets this source’s bit.
RETRACTWithdraw this source’s assertion. Clears this source’s bit. Tombstones the entity if all bits are cleared.
QUERYRead the current state of a single entity by ID. Served entirely from memory.
SUBSCRIBEReceive a real-time stream of change notifications for all entities of a given kind.

See the Writer’s Guide and Reader’s Guide for detailed semantics.

ConvergeDB uses last-write-wins on full entity records within each source. Across sources, assertions are merged, not arbitrated:

  • When a source asserts an entity, the server compares the new field data to the stored state at the byte level.
  • If the data is identical, no version bump occurs and no subscriber notification is sent. This is called deduplication.
  • If the data differs, the entity’s version is incremented and subscribers are notified.

Source bits are independent of field data. Asserting an entity always sets the source’s bit, even if the field data is identical.

Writes are fire-and-forget. The server does not acknowledge individual ASSERT or RETRACT operations.

Instead, the server batches writes within a configurable coalescing window (default: 20ms). Multiple writes to the same entity within a single window produce a single flush write. This dramatically reduces I/O for hot entities while keeping notification latency bounded.

See Write Coalescing for details.

Versions are server-assigned, monotonically increasing integers per entity. A version bump occurs only when:

  • The entity’s field data changes (byte-level comparison).
  • The entity transitions between alive and tombstoned states.

Source-set-only changes (for example, a second source asserting an entity with identical data) do not bump the version.

When all source bits are cleared from an entity (all sources have retracted), the entity is tombstoned. Tombstoned entities:

  • Remain visible to queries and subscriber notifications during a retention period (default: 5 minutes).
  • Are removed during compaction after the retention period expires.
  • Subscribers who were offline longer than the tombstone retention period must re-bootstrap to discover missed deletions.