Skip to content

ADR-0007: Identifiers (UUID vs ULID)

Status: Accepted
Related: ADR-0006 Event Envelope

Context

Identifiers must provide global uniqueness (for deduplication and references) and useful ordering (for human/debug sorting). Different use cases apply to event IDs (single events) and stream IDs (aggregate streams).

Decision

  • Event IDs (event_id): Use ULID (128-bit; Crockford Base32, 26 chars).
  • Generate monotonic ULIDs to avoid collisions within the same millisecond.
  • ULID is sortable by creation time, but global_seq remains the source of truth for ordering.
  • Stream IDs (stream_id): Use domain-scoped identifiers:
  • Prefer a stable ULID per aggregate instance (simple, uniform), or a natural key when it is globally unique and immutable (e.g., Session:2024-10-05_LDT_01).
  • Do not encode type inside the ID; type lives in stream_type.

Consequences

  • Human-friendly sorting of event_idaids debugging and log correlation.
  • Deterministic, unique IDs support idempotency and cross-system references.
  • Clear separation of concerns: identity via ULID, ordering via global_seq.