Skip to content

Architecture

Chronicle is a client–server event platform. Your application talks to a small kernel through gRPC/protobuf contracts; the kernel owns the event store and runs the processing that turns events into read models. The .NET client is the first-class, most mature experience, but the boundary is not .NET-only: the repository also ships TypeScript and Elixir clients/contracts generated from the same protocol.

Understanding this shape makes the rest of the docs click into place: client language, storage engine, processing runtime, and operating tools are separate choices that still share one event model.

Chronicle kernel

Your application

write

query

gRPC/protobuf

append / query

Chronicle clients

.NET · TypeScript · Elixir

.NET Orleans runtime

Event store

Observers

(projections · reducers · reactors)

Jobs · recommendations

replay · recovery

Storage

MongoDB · PostgreSQL · SQL Server · SQLite

Read models

(sinks)

Workbench + CLI

(operate)

OpenTelemetry

(logs · traces · metrics)

  • Client boundary — gRPC/protobuf contracts. The .NET client is the main developer experience; TypeScript and Elixir clients/contracts let other runtimes talk to the same kernel.
  • Kernel — the server. It validates and stores events, and runs the observers (projections, reducers, reactors) that react to them.
  • Orleans runtime — the kernel is built on .NET Orleans, using grains for stateful, distributed processing such as event sequences, observer state, jobs, reminders, and recovery.
  • Storage — the event log and read models persist here; MongoDB is the default, with PostgreSQL, Microsoft SQL Server, and SQLite available through the SQL storage implementation.
  • Read models / sinks — projections write their output to a sink; your queries read from there.
  • Workbench and CLI — web and terminal tools for inspecting and operating the store: events, observers, read models, recommendations, jobs, failed partitions, and replay.
  • OpenTelemetry — Chronicle exports logs, traces, and metrics through standard OTLP configuration.

The event log is often the system’s longest-lived asset. Chronicle keeps that boundary explicit:

  • Client language is a choice. .NET is first-class and receives the richest API, analyzers, hosting integration, and testing helpers. The gRPC/protobuf contract keeps Chronicle accessible from other runtimes too; the repository currently ships TypeScript and Elixir clients/contracts generated from that protocol.
  • Storage is a deployment choice. You can run MongoDB locally by default, or configure PostgreSQL, Microsoft SQL Server, or SQLite when that fits your platform better. The event model above the storage layer does not change.
  • Operations are part of the model. Observers track their position, failed partitions are recorded, jobs have state, recommendations can be listed and performed, and replay is a first-class operation.

The single most important flow to internalize:

Read modelProjectionKernelYour appRead modelProjectionKernelYour appAppend AuthorRegisteredAppended (committed to the log)Deliver eventUpdate read modelQuery authorsCurrent view

The append and the read-model update are separate steps. The event is committed first; the projection updates the read model shortly after. That gap is why read models are eventually consistent — usually imperceptible, occasionally something to design around.

Keeping event processing in the kernel means your application stays thin: it expresses intent (append this fact, run this query) and the kernel handles ordering, delivery, replay, projection, observer state, and recovery. Because the kernel is built on Orleans, that processing can scale and recover independently of your app, and multiple apps can share one store.