CosmoKv 2.2.1
dotnet add package CosmoKv --version 2.2.1
NuGet\Install-Package CosmoKv -Version 2.2.1
<PackageReference Include="CosmoKv" Version="2.2.1" />
<PackageVersion Include="CosmoKv" Version="2.2.1" />
<PackageReference Include="CosmoKv" />
paket add CosmoKv --version 2.2.1
#r "nuget: CosmoKv, 2.2.1"
#:package CosmoKv@2.2.1
#addin nuget:?package=CosmoKv&version=2.2.1
#tool nuget:?package=CosmoKv&version=2.2.1
CosmoKv
An embeddable, MVCC-transactional, LSM-tree key/value store for .NET 10. A C# port of Dgraph's Badger v4, redesigned for idiomatic .NET (ValueTask, IAsyncEnumerable<T>, ReadOnlySpan<byte>).
CosmoKv is a single-process, single-writer-many-reader store. Open one Db per directory; from there it's all async, lock-free reads, and snapshot-isolated transactions.
Features
- MVCC snapshot-isolation transactions. Every commit gets a monotonic timestamp; readers see a stable snapshot at their
BeginTransactioncall. Read-write conflicts are detected at commit time and raiseConflictException. A WaterMark prunes the oracle's committed-txn list so long-running processes don't grow it unbounded. - WAL-backed durability. Every write goes through a write-ahead log before the in-memory memtable;
SyncWrites=truefsyncs on every entry. Crash recovery is exercised by an in-process kill-fuzz test and a subprocess crash harness that asserts everySYNCEDline is recoverable afterProcess.Kill. - Value log indirection. Values larger than
ValueThreshold(default 1 KiB) live in.vlogfiles; LSM rows hold a 12-byte pointer. Reclaim space viaDb.RunValueLogGcAsync. - Background compaction. A worker scores levels and runs L0→L1→…→L_n compactions; tombstones are discarded at the bottom level. L0 backpressure stalls writers cleanly when the compactor can't keep up. Old SSTable files are removed via
FileShare.Deleteso deletion works on POSIX and Windows even with open reader handles. - Sharded LRU block cache (default 256 MiB, 16 shards) keyed by
(fileId, blockOffset). Decodes once, serves many — cached point Gets are 3× faster than uncached. - Pluggable block compression —
None,LZ4(K4os.Compression.LZ4),Snappy(IronSnappy),Zstd(ZstdSharp.Port). Codec id is stored per block so a single database can mix compression types across its history. - TTL enforcement. Set
expiresAton a write and the entry stops being visible toGetAsync/IterateAsyncafter that wall-clock time. A background sweeper (default 60 s cadence, capped at 10 000 ops/cycle) writes tombstones for expired user-keys;Db.SweepExpiredAsynctriggers a manual pass. - Lock-free memtable. Writes use CAS-link inserts on a concurrent skiplist (
Interlocked.CompareExchangeon per-levelNextpointers). Toggleable viaDbOptions.UseLockFreeMemtable(default on). IAsyncEnumerable<Item>iteration with forward/reverse, prefix filter, andAllVersionsmode. LazyItem.ReadValueAsyncdefers vlog dereference until the consumer needs the bytes.- Change-feed subscriptions.
db.Subscribe(prefix)returns anIAsyncEnumerable<ChangeEvent>of every subsequent commit whose user-key matches the prefix. Each subscriber gets a bounded drop-oldest channel so slow consumers can't stall the writer. - Bulk streaming.
KvStream(export) +KvStreamWriter(bulk-load) shipIAsyncEnumerable<KvList>pipelines. The writer builds L0 SSTables directly, bypassing the WAL — measurably faster than per-keySetAsyncfor large fresh loads. Used by backup/restore. - Backup / Restore.
db.BackupAsync(stream)writes the live keyspace as a portable, CRC64-protectedCOSMOBAKstream;Db.RestoreAsync(targetOptions, stream)rehydrates a fresh database from one. Tamper + truncation are detected by the trailer CRC. - Encryption at rest. Set
DbOptions.EncryptionKeyto a 32-byte master key and every SST block, WAL frame, and vlog frame is AEAD-encrypted with AES-256-GCM. AKEYREGISTRYin the db directory holds the wrapped DEK; the master key never touches disk. Tampered ciphertext fails the AEAD tag check; wrong master key fails to unwrap. - OpenTelemetry instrumentation.
Meter("CosmoKv")exposes write/read/commit/conflict/flush/compaction counters and latency histograms;ActivitySource("CosmoKv")emits spans for Set/Delete/Get/Commit/Flush/Compaction/VlogGc. Listen viadotnet-counters,dotnet-trace, or OTelAddMeter("CosmoKv").AddSource("CosmoKv"). Zero overhead when no listener is attached. - Pooled buffers on the hot path.
WalWriter,ValueLogFile, andTableBuilderrent their framing buffers fromArrayPool<byte>.Shared— large-value writes allocate up to 81% less than the naive implementation.
Quick example
using CosmoKv;
await using var db = await Db.OpenAsync(DbOptions.Default("/tmp/mydb"));
// Auto-commit single writes
await db.SetAsync("hello"u8.ToArray(), "world"u8.ToArray());
byte[]? v = await db.GetAsync("hello"u8.ToArray()); // [ 'w','o','r','l','d' ]
// Multi-key atomic transactions
await using (var txn = db.BeginTransaction(update: true))
{
txn.Set("a"u8.ToArray(), "1"u8.ToArray());
txn.Set("b"u8.ToArray(), "2"u8.ToArray());
await txn.CommitAsync();
}
// Sorted iteration with a prefix
await foreach (var item in db.IterateAsync(IteratorOptions.WithPrefix("user:"u8.ToArray())))
{
byte[] value = await item.ReadValueAsync();
// ...
}
Performance
Numbers from bench/CosmoKv.Benchmarks/ on Apple M1, APFS, SyncWrites=false,
1 warmup + 3 measurement iterations. Reproduce with
dotnet run -c Release --project bench/CosmoKv.Benchmarks -- --filter '*'.
| Workload | Per-op | Throughput |
|---|---|---|
| Point Get, 10 000 keys (cached, default) | 0.68 µs | ~1.47 M ops/s |
| Point Get, 100 000 keys (cached, default) | 1.02 µs | ~980 k ops/s |
| Range scan, 100 000 keys (cached) | 182 ns/key | ~5.5 M keys/s |
| Sequential Set, 128 B values | 1.36 µs/op | ~735 k ops/s |
| Sequential Set, 1024 B values (vlog path) | 5.06 µs/op | ~197 k ops/s |
WriteBatch Set, 1024 B values (vlog path) |
6.38 µs/op | ~157 k ops/s |
Allocations on the write path are pool-backed: a 10 000 × 1024-byte random write batch allocates just 2.5 MB, down from 13.4 MB in the unpooled baseline (-81 %).
Cross-platform validation: 228 library + 11 CLI tests (239 total) pass on macOS Apple Silicon; 228 library tests pass on Windows 11 ARM64 (Parallels guest, native NTFS).
See docs/benchmarks.md for the full tables across hosts and a
breakdown of how pooling + ValueTask each contributed.
Installation
CosmoKv is published to nuget.org:
dotnet add package CosmoKv
There's also a CLI:
dotnet tool install -g CosmoKv.Cli
cosmokv --help
Or as a project reference if you've cloned the repo:
<ItemGroup>
<ProjectReference Include="path/to/CosmoKv/src/CosmoKv/CosmoKv.csproj" />
</ItemGroup>
Requires .NET 10 (LangVersion latest, Nullable enabled). CosmoKv depends on
System.IO.Hashing 9.0 plus the block-compression codecs K4os.Compression.LZ4,
IronSnappy, and ZstdSharp.Port.
Documentation
- docs/getting-started.md — first-time user guide with worked examples.
- docs/examples.md — end-to-end snippets: counters, transfers, bulk load, secondary indexes, snapshot reports, time-travel reads, vlog GC.
- docs/api-reference.md — every public type and method.
- docs/benchmarks.md — full benchmark tables across macOS + Windows-NTFS, plus the pool vs. ValueTask attribution.
- docs/internals.md — architecture, on-disk formats, MVCC mechanics, tuning, and a note on what's intentionally not implemented.
Building from source
git clone <repo>
cd CosmoKv
dotnet build # builds the library, tests, and bench
dotnet test --filter "Category!=Stress" # fast loop, ~15 s
dotnet test --filter "Category=Stress" # bank + fuzz, ~30 s default
dotnet run -c Release --project bench/CosmoKv.Benchmarks -- --filter '*' # BenchmarkDotNet
Test coverage: 228 library tests + 11 CLI tests + ~10 stress tests, all green on macOS (Apple Silicon, .NET 10) and Windows 11 ARM64 (Parallels guest, .NET 10.0.300).
Status
2.1.0 — every v1.0 deferred item shipped. Phases 17–23 closed out the rest of the
deferred-features list: ReadOnly enforcement, multi-worker compactor, txn iter
reads-own-writes (v1.1), write-path lock split (v1.2), change-feed subscriptions +
bulk stream/writer (v1.3), backup/restore (v1.4), AES-256-GCM encryption at rest with
KeyRegistry (v2.0), and the cosmokv CLI (v2.1). See CHANGELOG.md
for the full version-by-version log.
Out of scope (and likely to stay that way):
- On-disk format compatibility with Badger files (CosmoKv has its own wire format).
- Multi-process access to one directory (no file lock; still single-process).
See docs/internals.md for the full deferred-features list and rationale.
Releasing
NuGet publish is automated by .github/workflows/publish.yml.
To cut a release:
git tag v2.1.0
git push origin v2.1.0
The workflow restores, builds in Release, runs the non-stress test suite, packs both CosmoKv.<version>.nupkg (library) and CosmoKv.Cli.<version>.nupkg (CLI tool) with the tag's version (the leading v is stripped), pushes them to nuget.org, and creates a GitHub Release with auto-generated notes and the packages attached.
For a manual run without tagging, dispatch the workflow from the Actions tab and pass the version as an input.
Required repository secret: NUGET_API_KEY — an API key from nuget.org/account/apikeys scoped to push the CosmoKv package.
The build is reproducible (ContinuousIntegrationBuild=true under GitHub Actions) and Source Link is embedded, so consumers can step-into-source on debug.
License
Apache License 2.0. CosmoKv is a port of the original Badger, which is also Apache 2.0.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Cosmo.Transport (>= 1.0.2)
- IronSnappy (>= 1.3.1)
- K4os.Compression.LZ4 (>= 1.3.8)
- System.IO.Hashing (>= 9.0.0)
- ZstdSharp.Port (>= 0.8.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CosmoKv:
| Package | Downloads |
|---|---|
|
CosmoSQLClient.CosmoKv
CosmoKv driver for CosmoSQLClient — runs a T-SQL subset directly on top of an embedded CosmoKv LSM-tree store. Single-process, transactional, schema-on-write. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.1 | 25 | 5/20/2026 |
| 2.2.0 | 26 | 5/20/2026 |
| 2.1.9 | 57 | 5/20/2026 |
| 2.1.5 | 154 | 5/18/2026 |
| 2.1.4 | 76 | 5/18/2026 |
| 2.1.3 | 69 | 5/18/2026 |
| 2.1.2 | 72 | 5/18/2026 |
| 2.1.1 | 79 | 5/18/2026 |
| 2.1.0 | 69 | 5/18/2026 |
| 2.0.0 | 76 | 5/18/2026 |
| 1.4.0 | 78 | 5/18/2026 |
| 1.3.1 | 78 | 5/18/2026 |
| 1.2.0 | 72 | 5/18/2026 |
| 1.1.0 | 74 | 5/18/2026 |
| 1.0.0 | 75 | 5/18/2026 |
| 0.1.0 | 97 | 5/18/2026 |