Cratis.Choreography.Storage 2.3.0

Prefix Reserved
dotnet add package Cratis.Choreography.Storage --version 2.3.0
                    
NuGet\Install-Package Cratis.Choreography.Storage -Version 2.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cratis.Choreography.Storage" Version="2.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cratis.Choreography.Storage" Version="2.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Cratis.Choreography.Storage" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cratis.Choreography.Storage --version 2.3.0
                    
#r "nuget: Cratis.Choreography.Storage, 2.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cratis.Choreography.Storage@2.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cratis.Choreography.Storage&version=2.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Cratis.Choreography.Storage&version=2.3.0
                    
Install as a Cake Tool

<div align="center"> <a href="https://www.cratis.io"> <img src="full-logo.png" alt="Cratis Choreography" width="480"> </a>

<h3 align="center">Cratis Choreography</h3>

<p align="center"> Cratis Choreography is the runtime for durable business processes on Microsoft Orleans — workflows, state machines and jobs that survive restarts, with pluggable storage and one-call silo hosting. <br /> <a href="https://www.cratis.io/choreography/"><strong>Explore the docs »</strong></a> <br /> <br /> <a href="#-getting-started">Getting Started</a>  ·  <a href="https://github.com/cratis/Choreography/issues/new?labels=bug">Report a Bug</a>  ·  <a href="https://github.com/cratis/Choreography/issues/new?labels=enhancement">Request a Feature</a>  ·  <a href="https://discord.gg/kt4AMpV8WV">Join the Discord</a> </p>

<p align="center"> <a href="https://discord.gg/kt4AMpV8WV"> <img src="https://img.shields.io/discord/1182595891576717413?label=Discord&logo=discord&color=7289da" alt="Discord"> </a> <a href="http://nuget.org/packages/cratis.choreography"> <img src="https://img.shields.io/nuget/v/Cratis.Choreography?logo=nuget" alt="NuGet"> </a> <a href="https://github.com/Cratis/Choreography/actions/workflows/dotnet-build.yml"> <img src="https://github.com/Cratis/Choreography/actions/workflows/dotnet-build.yml/badge.svg" alt=".NET Build"> </a> <a href="https://github.com/Cratis/Choreography/actions/workflows/publish.yml"> <img src="https://github.com/Cratis/Choreography/actions/workflows/publish.yml/badge.svg" alt="Publish"> </a> <a href="./LICENSE"> <img src="https://img.shields.io/badge/license-MIT-blue" alt="License"> </a> </p> </div>


Cratis Choreography runs long-lived, stateful behavior on Orleans so it survives restarts, deactivation and moves between silos. It holds a workflow engine that runs a business process defined as a graph of nodes, state machines (plain, and event-sourced through Chronicle), a durable job system for work that outlives a request, a storage API the job state persists through — with MongoDB, SQL and in-memory providers — and the silo hosting tooling that co-hosts Orleans next to an application in one call.

It is consolidated here from Chronicle (the job engine, the workers pattern, the serializers), Direct (the hosting knowledge) and Studio (the package-alignment guard) — so all three consume one canonical implementation instead of three diverging copies. The repository has no dependency on Chronicle; Chronicle is a consumer, like every other Cratis service.

For core values and principles, read our core values and principles.

✨ Key Features

🔀 Workflows and State Machines

Workflows as Graphs A business process is a versioned graph of Trigger, Action, Decision, Wait, Approval, ForEach and Join nodes that runs durably on grains and is rebuilt from its own journal of facts
Pinned Definitions A run pins the definition it was admitted against, so changing a workflow never changes a run in flight
Safe Effects Node work runs as jobs with retries and an idempotency key; an ambiguous outcome stops the run for reconciliation instead of repeating the effect
State Machines StateMachine<TStoredState> makes a grain's lifecycle explicit states and transitions
Event-sourced With Cratis.Choreography.Chronicle, transitions are Chronicle events and the model is a Chronicle read model

↩️ Operation History and Undo/Redo

Operation History A logical user action with a stable id, scope, actor, kind, lifecycle and the event sequence numbers it produced — append-only, queryable by scope and actor
Explicit Reversal A fluent definition supplies the inverse command and the current-state rules; the engine never infers one from events
Undo as New Activity Undo and redo run as new operations targeting the original, multi-event operations as one unit, and a blocked latest operation is never skipped

⚙️ Job System

Durable Jobs Work that outlives a request — replay, migration, provisioning — persisted through the storage API and rehydrated when the silo restarts
Steps as Grains Each step is its own Orleans grain, so slow or hanging steps never stall each other and run in parallel, bounded by a throttle
Plan then Perform PrepareSteps says what will happen before any of it happens — watchable progress rather than a spinner
At-least-once A step in flight when the host went down is performed again on resume; progress checkpoints are debounced and time-flushed
Fail-open One failed step fails the job's completion status — never the application; the history says which step was which
Lifecycle Control Stop, resume and delete through the jobs manager grain, or the client-facing commands consumers build on it

🗄️ Pluggable Storage

Scope + Namespace Seam IJobsStorage.GetFor(scope, namespace) — opaque values every consumer maps its identity onto (Chronicle: event store and namespace; an application: tenant or service)
MongoDB Provider Polymorphic request BSON serialization, indexes on status and type, conventions, configurable database naming
SQL Provider EF Core — SQL Server, PostgreSQL, SQLite — with full provider and connection flexibility per scope
In-memory Provider For spec hosts and services that do not need jobs to survive a restart

🖥️ Silo Hosting

One Call AddCratisChoreography brings the whole job system: grains, storage providers, serializers, type discovery, throttle and options
Clustering Localhost for development, durable MongoDB membership for running more than one instance
Reminder Safety The 9.x MongoDB provider's reminder table hangs the 10.x reminder service — the hosting keeps reminders on the in-memory service and the knowledge lives here once
Alignment Guard Cratis.Choreography depends directly on Orleans 10 Reminders for .NET 8, 9 and 10, so the MongoDB provider's Orleans 9 dependency cannot split a consumer's graph. The buildTransitive target also fails Release builds if Reminders drifts from Server.

🩹 Startup Patching

Patches by Convention Implement ICanApplyPatch and the patch is discovered — it runs once per store, oldest first, with your services injected
Safe on Rolling Upgrades Only the newest host applies patches; an older host applies nothing, and the patch manager moves to a newer host's silo before it patches
Recorded After They Run A patch that fails stops the host from starting and is attempted again on the next start
Pluggable Records The record of applied patches lives in MongoDB, SQL or memory, once per store

🔧 Building Blocks

Workers The background-task pattern the job steps run through — also usable directly
Typed Grain Keys KeyHelper combines and parses compound grain keys (scope#namespace)
Cratis Serializers Orleans codecs for concepts (ConceptAs<T>), OneOf, expando objects and LINQ collections, plus a JSON fallback carrying the job state converter
Public Logging Surface BeginJobScope/BeginJobStepScope and the [LoggerMessage] partials a consumer's own jobs read through

📦 Packages

Package What it holds
Cratis.Choreography The workflow engine, state machines, the job engine, Workers, typed grain keys, serializers, silo hosting
Cratis.Choreography.Storage The jobs and patch storage APIs, the scope resolver, the in-memory providers
Cratis.Choreography.Storage.MongoDB The MongoDB jobs and patch storage provider
Cratis.Choreography.Storage.Sql The SQL jobs and patch storage provider (EF Core; net10, matching EF Core 10)
Cratis.Choreography.Chronicle Event-sourced state machines and workflows driven by Chronicle events

🚀 Getting Started

You need the .NET 10 SDK and, for anything but the in-memory storage, a MongoDB server.

dotnet add package Cratis.Choreography
dotnet add package Cratis.Choreography.Storage.MongoDB
using Cratis.Choreography.Hosting;
using Cratis.Choreography.Setup;
using MongoDB.Driver;

var builder = WebApplication.CreateBuilder(args);

builder.AddCratisChoreography(new CratisChoreographyOptions
{
    ClusterId = "my-service",
    ServiceId = "my-service"
});

builder.Services.AddCratisChoreographyMongoDBJobsStorage(
    new MongoClient("mongodb://localhost:27017"));

var app = builder.Build();
app.Run();

Define a job and its steps — grains, discovered automatically, nothing to register:

public record ProvisionTenant(string TenantId, string[] Features) : IJobRequest;

public interface IProvisionTenant : IJob<ProvisionTenant>;

public class ProvisionTenantJob : Job<ProvisionTenant, JobState>, IProvisionTenant
{
    // Completed jobs remove themselves by default; keep this one queryable.
    protected override bool KeepAfterCompleted => true;

    protected override Task<IImmutableList<JobStepDetails>> PrepareSteps(ProvisionTenant request) =>
        Task.FromResult<IImmutableList<JobStepDetails>>(
            request.Features.Select(feature => new JobStepDetails(
                Type: typeof(IProvisionFeatureStep),
                Id: JobStepId.New(),
                Key: new JobStepKey(JobId, string.Empty, string.Empty),
                Request: feature,
                ResultType: typeof(string))).ToImmutableList());
}

Start it through the jobs manager — the two strings are the storage scope and namespace:

var manager = grainFactory.GetJobsManager("my-service", string.Empty);
var result = await manager.Start<IProvisionTenant, ProvisionTenant>(new(id, ["billing"]));

Starting returns as soon as the job exists. Stop the service mid-flight and start it again — the job picks itself back up. That is the point.

Read the full walkthrough in the getting-started guide.

🧪 Testing

The repository carries three spec tiers:

  • Unit specs (Source/*/.Specs) — 76+ Orleans TestKit specs covering the job grain lifecycle, the throttle, the checkpoint debouncer, the serializers and the storage scope resolution.
  • Integration specs (Integration/Jobs.Integration) — end-to-end against a real co-hosted silo and a real MongoDB: start a job, run its steps as real grains, persist the state. CI runs a MongoDB service container so these gate every pull request.
  • Consumer suites — Chronicle's kernel spec suite (3,496 specs) runs against the package engine through its rip-out integration.

🤝 Support

Cratis is an open community, and we are glad to help users, teams evaluating the stack, and contributors.

Channel Details
Discord Join the community on Discord for questions and discussions
GitHub Issues Report bugs or request features
Documentation Read the docs at cratis.io/choreography

👷 Contributing

If you want to jump into building this repository and possibly contributing, refer to contributing.

Prerequisites

  • .NET 10 SDK
  • Docker — the integration specs and the MongoDB spec suites run against containers

Build and test

dotnet build
dotnet test

The integration specs expect a MongoDB on localhost:27017 (or a running Docker daemon).

📄 License

Cratis Choreography is free software distributed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on Cratis.Choreography.Storage:

Package Downloads
Cratis.Chronicle.Testing

Testing helpers for Cratis Chronicle - the open-source (MIT) event-sourcing database and runtime. In-process kernel and in-memory storage for testing event-sourced applications.

Cratis.Chronicle.XUnit.Integration

xUnit integration-testing support for Cratis Chronicle - the open-source (MIT) event-sourcing database and runtime. Fixtures and helpers for integration tests against an in-process kernel.

Cratis.Choreography

Runtime for durable business processes on Orleans - workflows, state machines, jobs, workers, typed grain keys, serializers and silo hosting tooling

Cratis.Choreography.Storage.MongoDB

MongoDB storage provider for the Cratis.Choreography job system

Cratis.Choreography.Storage.Sql

SQL storage provider (EF Core: SQL Server, PostgreSQL, SQLite) for the Cratis.Choreography job system

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.3.0 360 11/5/2026
2.2.1 71 11/5/2026
2.2.0 349 11/4/2026
2.1.2 6,423 11/4/2026
2.1.1 1,289 11/4/2026
2.1.0 72 11/3/2026
2.0.0 246 11/3/2026