EmbedDB 0.2.0

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

EmbedDB (Embedded AOT Document Database)

EmbedDB is a lightweight, high-performance, in-memory embedded document database designed specifically for .NET 9.0 with 100% Native AOT (Ahead-of-Time) compilation support.

It keeps all data in memory for blazing-fast access while providing durable, crash-safe persistence to disk using compressed (GZipped) JSON files.

🌟 Key Features

  • 100% Native AOT Compatible: Zero reflection used at runtime. Relies entirely on System.Text.Json Source Generators.
  • In-Memory Document Store: Stores collections of POCOs (Plain Old CLR Objects) in memory for microsecond query times.
  • MVCC (Multi-Version Concurrency Control): Implements Copy-On-Write (COW) snapshot isolation. Readers never block writers, and writers never block readers.
  • Thread-Safe: Utilizes ReaderWriterLockSlim to allow multiple concurrent readers and exclusive writers.
  • Crash-Safe Atomic Saves: Uses a "write-to-temp and atomic-rename" strategy combined with FileStream.Flush(true) to guarantee zero data corruption during power failures or system crashes.
  • Compressed Persistence: Data is persisted as GZipped JSON to minimize disk footprint.
  • Strict Mutation Control: Exposes read-only snapshots (IReadOnlyList<T>) for LINQ queries. All modifications (Add/Update/Delete) are strictly controlled through the database engine to maintain state integrity.

📋 Prerequisites

  • .NET 9.0 SDK or higher

🚀 Quick Start

1. Define Your Models and JSON Context

Because AOT does not support runtime reflection, you must define your entities and register them in a JsonSerializerContext.

using System.Text.Json.Serialization;

public class User
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public int Age { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Title { get; set; } = string.Empty;
    public decimal Price { get; set; }
}

// Register ONLY the entity types (not List<T>)
[JsonSourceGenerationOptions(WriteIndented = false)]
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(Product))]
internal partial class AppJsonContext : JsonSerializerContext { }

2. Initialize the Database

Register your entities using the fluent API and initialize the database to load existing data from the disk.

using var db = new EmbedDatabase("my_data.db.gz"); // or empty string for in-memory only

db.Register(AppJsonContext.Default.User)
  .Register(AppJsonContext.Default.Product);

db.Initialize(); // Loads data from disk into memory

3. Perform CRUD Operations

Get strongly-typed collections and perform thread-safe mutations.

var users = db.GetCollection<User>();
var products = db.GetCollection<Product>();

// Add
users.Add(new User { Id = 1, Name = "Alice", Age = 28 });

// Add Range
products.AddRange(new[] {
    new Product { Id = 101, Title = "Laptop", Price = 1200.00m },
    new Product { Id = 102, Title = "Mouse", Price = 25.50m }
});

// Update (Conditional)
users.Update(
    match: u => u.Id == 1, 
    mutator: u => u.Age = 29
);

// Delete (Conditional)
int deletedCount = products.Delete(p => p.Price < 10.0m);

4. Querying Data (LINQ)

Queries are executed against an immutable, read-only snapshot of the current state.

// Simple count
int totalUsers = users.Query.Count();

// Complex LINQ
var expensiveItems = products.Query
    .Where(p => p.Price > 100)
    .OrderByDescending(p => p.Price)
    .Select(p => p.Title)
    .ToList()
);

🏗️ Architecture & Design Decisions

Concurrency & MVCC

The database uses a Copy-On-Write (COW) pattern. When a write operation occurs, the engine creates a shallow copy of the affected collection, applies the mutations to the copy, and then atomically swaps the memory reference.

  • Readers receive a snapshot of the list reference at the exact moment they requested it. They never experience locking delays.
  • Writers hold an exclusive lock only during the mutation and the subsequent disk I/O operation.

Durability & Crash Safety

Prevent file corruption during unexpected shutdowns. If a crash occurs during saving data, the main database file remains untouched and intact.

🛠️ Installation

NuGet Package Manager

Install-Package EmbedDB

.NET CLI

dotnet add package EmbedDB

🧭 Roadmap (TODO)

We are continuously working to improve EmbedDB. Here are the planned features for upcoming releases:

  • Strict Deep Immutability Enforcement: Currently, the collections are strictly read-only, but the entities inside the snapshot remain mutable reference types. Future versions will enforce deep immutability. This will be achieved by either requiring immutable C# record types, returning deep-cloned objects/proxies on read, or implementing structural sharing. This guarantees that data can only be modified through the explicit Update pipeline, completely eliminating accidental side-effects or unauthorized mutations from external code.

  • WAL (Write-Ahead Logging): Transitioning from full-state atomic saves to a Write-Ahead Log mechanism for even faster write operations and point-in-time recovery capabilities.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🤝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to open an issue or submit a pull request.

Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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.
  • net9.0

    • No dependencies.

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
0.2.0 142 6/21/2026
0.1.0 104 6/19/2026