Skip to content

Dynamic Consistency Boundary (DCB)

Why DCB exists and how it actually works

Streams are great for per-aggregate consistency. They fall apart when a rule spans multiple streams:

  • unique usernames across all users
  • no double-booking across all rooms
  • invoice numbers that never collide

Traditional event sourcing pushes those into sagas and compensations. DCB keeps the rule in one place by letting you check a query, not a stream.

DCB has three moving parts:

  1. Tags on events (opaque strings like username:alice)
  2. Query that matches events by type and/or tags
  3. Append condition that fails if any matching events appear after a position you already saw

The flow looks like this:

readByQuery(query) -> events + lastPosition
decide(events) -> new event
append(events, { failIfEventsMatch: query, after: lastPosition })

If someone else writes a conflicting event in between, your append fails. No saga. No compensation.

DeltaBase keeps the stream API intact and adds a streamless DCB API.

  • Stream path: readStream() + appendToStream()
  • DCB path: readByQuery() + append()

Both can coexist. Use DCB only where you need cross-stream guarantees.

Use DCB when:

  • the rule spans multiple streams
  • you need global uniqueness or limits
  • you want one event to affect multiple entities

Use streams when:

  • the rule is per aggregate
  • your invariants live inside one stream
  • you care about per-stream ordering and versioning
  • It is not a database transaction across aggregates
  • It does not prevent all races, only the ones you model in the query
  • It does not replace streams for aggregate-level logic

DCB is a targeted tool. Use it where it matters.