Core Concepts

Event sourcing is simple: store facts, derive state. But simple doesn't mean obvious. These concepts explain the mental model.

Events are facts

An event says "this happened." It's not a command ("do this") or a state ("this is"). It's history:

  • order_was_placed not place_order
  • user_had_email_updated not update_email

Events are immutable. Once written, they never change. If you need to "undo," write a compensating event.

Aggregates are derived

An aggregate is current state computed from all its events. There's no "update the user record." There's "write a user_was_updated event, compute state fresh."

This seems inefficient. It's not: - j17 caches aggressively - Events are small (hundreds of bytes) - Computation is fast (Zig handlers) - You get history for free

The spec defines everything

Your spec is JSON that declares: - What aggregate types exist - What events can happen - How events transform state (handlers) - Who can trigger events (agents)

No code deployment needed. Upload a new spec, behavior changes immediately.

Handlers are pure functions

A handler takes (state, event) and returns new state. No side effects, no external calls. Just data transformation.

state + event -> handler -> new_state

Tick provides 17 declarative operations in four categories: basic (set, merge, append, remove, increment, decrement), array (filter, map, update_where, upsert, append_unique), dynamic key (set_at, merge_at, remove_at, increment_at), and control flow (conditional, let).

This makes them: - Testable (input -> expected output) - Cacheable (same input, same output) - Parallelizable (no shared state)

Time is explicit

Every event has a timestamp. Query historical state:

GET /order/123?at=1705312800  # State on Jan 15

Audit trails are free. Just look at the events.

Consistency is optional

j17 supports three OCC modes: internal (default) for automatic request-time safety, external (via previous_length) for read-modify-write consistency, and disabled (via skip_occ) for append-only patterns. Pick the right model for your use case.

Learn more

Can't find what you need? support@j17.app