Core Concepts
Events and Positions
Events are the fundamental unit of data in UmaDB. Each event is stored with a monotonically increasing position that serves as its unique identifier in the global event sequence.
Every event stored in UmaDB is made up of four main parts:
- Event type — This is a label that describes what kind of event it is, such as
"OrderCreated"or"PaymentProcessed". It helps you understand and categorize what happened. - Data — This is the actual content of the event, stored in a compact binary form. It can hold any structured information your application needs — for example, details of an order or a payment.
- Tags — Tags are attached to the event so that you can find or filter events later. For example, you might tag an event with
"customer:123"or"region:EU". - Position — Every event is given a unique number when it’s written to the database. These numbers always increase, so they show the exact order in which events were added.
Event positions are:
- Monotonically increasing: Each appended event receives
position = last_position + 1. - Globally unique: No two events share the same position.
- Sequential: No gaps in the sequence (positions 1, 2, 3, ...).
- Immutable: Once assigned, an event's position never changes.
Tags and Queries
Tags enable efficient filtered reading of events. A tag is an arbitrary string. Common patterns include:
- Entity identifiers:
"order:12345" - Categories:
"region:us-west" - Relationships:
"customer:789"
Queries specify which events to select based on event types and tags. A query is made up of a list of zero or more query items. Each query item describes a set of event tags and types to match against event records.
When matching events for a query, all events are matched in position order, unless any query items are given, then only those that match at least one query item. An event matches a query item if its type is in the query item types or there are no query item types, and if all the query item tags are in the event tags.
Queries are used both when reading events (to build a decision model or a materialized view) and when appending events (to implement optimistic concurrent control for a consistency boundary).
Queries define what part of the event history matters for building a decision model and for deciding whether a write is allowed. It’s flexible enough to express many business rules, such as uniqueness checks, idempotency, or workflow coordination, all without hardcoding fixed entity or aggregate boundaries in the database.
