ZeroAlloc.EventSourcing.Sqlite 1.0.0

dotnet add package ZeroAlloc.EventSourcing.Sqlite --version 1.0.0
                    
NuGet\Install-Package ZeroAlloc.EventSourcing.Sqlite -Version 1.0.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="ZeroAlloc.EventSourcing.Sqlite" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ZeroAlloc.EventSourcing.Sqlite" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ZeroAlloc.EventSourcing.Sqlite" />
                    
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 ZeroAlloc.EventSourcing.Sqlite --version 1.0.0
                    
#r "nuget: ZeroAlloc.EventSourcing.Sqlite, 1.0.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 ZeroAlloc.EventSourcing.Sqlite@1.0.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=ZeroAlloc.EventSourcing.Sqlite&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ZeroAlloc.EventSourcing.Sqlite&version=1.0.0
                    
Install as a Cake Tool

ZeroAlloc.EventSourcing.Sqlite

NuGet AOT

A SQLite-backed IEventStoreAdapter for ZeroAlloc.EventSourcing. Designed for embedded scenarios, single-node services, test harnesses, and AOT-published binaries.

What it is

  • A drop-in IEventStoreAdapter implementation that persists events to a single event_store table in a SQLite database.
  • AOT-clean: ships with PublishAot=true compatibility verified by a dedicated AOT smoke project. No reflection, no dynamic code generation.
  • * global stream support: every event is assigned a monotonic global_position, enabling cross-stream reads via StreamId.Global — the same shape as the PostgreSQL and SQL Server adapters.
  • Optimistic concurrency: enforced via expectedVersion checks inside a BEGIN IMMEDIATE transaction; conflicts return StoreError.Conflict(...) rather than throwing.

Install

dotnet add package ZeroAlloc.EventSourcing.Sqlite

Quick start

using Microsoft.Extensions.DependencyInjection;
using ZeroAlloc.EventSourcing;
using ZeroAlloc.EventSourcing.Sqlite;

var services = new ServiceCollection();

services
    .AddEventSourcing()
    .UseSqliteEventStore("Data Source=events.db");

// IEventTypeRegistry must be registered separately — see the core package docs.

UseSqliteEventStore registers SqliteEventStoreAdapter as IEventStoreAdapter and EventStore as IEventStore. By default it also calls EnsureSchemaAsync() once during the singleton factory so the event_store table exists before first use. Pass ensureSchema: false if you prefer to control schema bootstrap yourself (e.g. via a migration runner).

// Opt out of automatic schema bootstrap
services.AddEventSourcing().UseSqliteEventStore(connectionString, ensureSchema: false);

// Then run it manually at a time of your choosing
var adapter = sp.GetRequiredService<IEventStoreAdapter>() as SqliteEventStoreAdapter;
await adapter!.EnsureSchemaAsync();

The * global stream

Reading from StreamId.Global (alias *) returns events from every stream in commit order:

await foreach (var raw in adapter.ReadAsync(StreamId.Global, StreamPosition.Start, ct))
{
    // raw.Position is the global_position (monotonic across all streams)
    // raw.EventType, raw.Payload, raw.Metadata are the usual per-event values
}

Inside a write transaction the adapter reads MAX(global_position) and assigns the next contiguous values. SQLite is single-writer, so global ordering is deterministic and gap-free — no skip-locks or sequence-cache surprises.

Health checks

Add a health check that probes the database with SELECT 1:

services.AddHealthChecks()
    .AddSqliteEventStore("Data Source=events.db");

Default registration name is sqlite-event-store. Override via the name parameter.

AOT attestation

This package is exercised by the ZeroAlloc.EventSourcing.Sqlite.AotSmoke project, which:

  • Publishes with PublishAot=true and InvariantGlobalization=true.
  • Gates IL2026, IL2067, IL2075, IL2091, IL3050, and IL3051 as build errors.
  • At runtime, appends an event and reads it back via both per-stream and * global reads.

A clean publish + exit-0 run is required to ship a new version.

Connection strings

// File-based (typical for embedded production)
"Data Source=events.db"

// File-based with WAL mode (better concurrency on multi-reader workloads)
"Data Source=events.db;Cache=Shared"
// Then run "PRAGMA journal_mode=WAL;" once after EnsureSchemaAsync.

// In-memory, shared cache (typical for tests)
"Data Source=file:test-abc?mode=memory&cache=shared"
// Hold a keep-alive SqliteConnection open for the lifetime of the test so the
// shared-cache backing store is not collected when transient connections close.

// Strictly per-connection in-memory (not useful — each connection sees its own DB)
"Data Source=:memory:"

Concurrency model

SQLite is a single-writer database. The adapter issues BEGIN IMMEDIATE (via IsolationLevel.Serializable on Microsoft.Data.Sqlite) so concurrent appenders queue cleanly at the connection layer instead of racing into "database is locked" errors. For high-throughput workloads, prefer the PostgreSQL or SQL Server adapter; SQLite shines for embedded apps, single-process services, edge deployments, and integration tests.

Roadmap

  • Live subscriptions: the current SubscribeAsync returns a polling subscription. A future release may use SQLite's data_change_notification_callback (the C-level update_hook) to push real-time notifications without polling. Tracked separately.
  • WAL bootstrap helper: an opt-in pragma_journal_mode=WAL switch on UseSqliteEventStore to enable WAL automatically.

Versioning

This package follows the ZeroAlloc.EventSourcing repository's SemVer + Conventional Commits + release-please workflow. The PublicAPI.Shipped.txt file in this project is the authoritative list of the public surface — anything not declared there is unshipped or internal.

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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 133 6/12/2026