Kahuna.Core
1.10.6
See the version list below for details.
dotnet add package Kahuna.Core --version 1.10.6
NuGet\Install-Package Kahuna.Core -Version 1.10.6
<PackageReference Include="Kahuna.Core" Version="1.10.6" />
<PackageVersion Include="Kahuna.Core" Version="1.10.6" />
<PackageReference Include="Kahuna.Core" />
paket add Kahuna.Core --version 1.10.6
#r "nuget: Kahuna.Core, 1.10.6"
#:package Kahuna.Core@1.10.6
#addin nuget:?package=Kahuna.Core&version=1.10.6
#tool nuget:?package=Kahuna.Core&version=1.10.6
🦎 Kahuna
<img width="946" height="693" alt="cli" src="https://github.com/user-attachments/assets/4ee77393-a0f0-48a3-b1e0-836dbf6cf3b0" />
Distributed systems are difficult to build correctly. Execution can be non-deterministic. Edge cases are hard to predict. These factors make it difficult to reason about correct solutions.
Kahuna is an open-source project. It gives developers ready-made solutions for three common problems in distributed systems:
- Distributed locking
- A distributed key/value store
- A distributed sequencer
Distributed Locking
Multiple nodes or processes often need access to the same resource. Kahuna synchronizes that access to prevent race conditions and to keep data consistent.
Distributed Key/Value Store
Kahuna provides ephemeral and persistent keyspaces, conditional mutations, historical reads and multi-key transactions. Persistent operations use partitioned Raft replication; ephemeral values remain in memory. Use it for metadata, caches, or application state.
Distributed Sequencer
Kahuna allocates ordered numeric ranges per named sequence, with optional idempotent reservations. Ordering is per sequence; independent sequences do not define a global event order. See the sequencer guide for block allocation and gap semantics.
User-Defined Functions
Kahuna Script can call custom C# functions registered by the operator or embedded host. This is useful when a .NET application needs cluster-side business logic without adding extra client round trips or moving the decision outside the transaction.
The guides below describe the guarantees and failure boundaries of these capabilities.
Kahuna is a Hawaiian word for an expert in any field. Historically, it referred to doctors, surgeons, dentists, priests, ministers, and sorcerers.
Read the documentation for architecture details, installation steps, and usage examples.
Installation
The quickest way to start a node is the .NET global tool:
dotnet tool install -g Kahuna.Server
kahuna-server
With no arguments, this command starts a standalone node on two listeners:
| Port | Protocol | Serves |
|---|---|---|
| 8081 | HTTP/1.1, HTTP/2, HTTP/3 | REST and gRPC |
| 8083 | cleartext HTTP/2 (h2c) | gRPC only |
These are the same ports that scripts/run-standalone.sh, the standalone container image and the
kahuna-cli default endpoint use, so every example in this repository reaches the node.
Port 8083 exists because a gRPC client cannot negotiate HTTP/2 on the plain HTTP port without
TLS. It carries no encryption and no authentication, so keep it on a trusted network. Pass
--grpc-cleartext-ports <port> to move it to another port.
The node stores key-value data and the Raft write-ahead log under the per-user data directory:
- Linux / macOS:
~/.local/share/kahuna - Windows:
%LOCALAPPDATA%\kahuna
The node prints both paths at startup. Set KAHUNA_HOME to change the location. You can also
pass --storage-path or --wal-path directly.
A node started this way serves cleartext only. HTTPS binds on a third port, 8082, only when you supply a certificate:
kahuna-server --https-certificate /path/to/certificate.pfx
With a certificate, the node does not bind the cleartext ports 8081 and 8083. Pass
--allow-plaintext-listener to keep them. To authenticate traffic between nodes with mutual TLS, see
docs/node-transport-security-guide.md.
A node that joins a cluster does not bind the cleartext gRPC port. Ask for it explicitly:
kahuna-server --initial-cluster host2:8081 host3:8081 --grpc-cleartext-ports 8083
The command-line client is a separate tool:
dotnet tool install -g Kahuna.Control
kahuna-cli
For a multi-node cluster, or to build from source, see the Docker images under docker/ and the
scripts in scripts/.
Architecture
<img src="https://github.com/user-attachments/assets/b60b213c-d12d-48a5-ba22-38fe99d2a590" height="350">
Partitioned storage and replication
Data operations route by key space and range (or hash) to a data partition and its leader. Each partition has its own Raft group. By default voter nodes host every partition; an explicit replication factor assigns per-partition replica sets. A non-hosting node forwards operations to the appropriate leader. Availability requires a voter quorum for the affected partition, not merely one surviving node.
Persistent mutations are replicated through Raft and applied to the backend asynchronously. The Raft WAL and application-durability floors protect committed state while backend flushes lag. Ephemeral mutations do not have Raft durability, and an in-memory backend/WAL cannot survive total process loss. A replication acknowledgement does not mean every follower's application or backend has caught up.
Transactions and visibility
Kahuna uses MVCC for staged values and historical revisions. A fixed read timestamp selects an as-of view, subject to retained history; latest transactional reads pin observations per key and can abort after a competing revision advances. They do not implicitly create one historical snapshot across all keys. Optimistic transactions validate dependencies, while pessimistic operations acquire locks; validation and staging-continuity fences remain necessary across leader changes.
Persistent transaction finalization replicates prepared intents and a canonical commit/abort decision.
Deferred settlement is the default: the decision can be durable before values are installed into the
backend, and readers resolve pending intents against that decision. An unresolved finalize answers
MustRetry; this is not proof that the transaction has no durable effects. Retry with the same
transaction identity. A terminal Aborted requires a new transaction.
Range movement and recovery
Registered key ranges can split and merge. Automatic triggers and placement/leader balancing depend on configuration and admissible moves; adding nodes does not promise proportional capacity. Under per-partition placement, range movement copies data to the destination replicas before routing cutover. Quiesce, generation fences and transaction-state handoff protect that transition; refusals are retryable.
A replica outside retained Raft history can be seeded from a whole-partition snapshot and replay the tail. Snapshot staging caps, disk space and install deadlines can limit recovery. Backups and PITR are separate operator-triggered mechanisms, subject to coverage and retention rules.
The repository guides cover the implemented semantics in more detail:
- Transaction reads and locks
- Transaction lifecycle and interactive coordinator
- Durable settlement and upgrade compatibility
- Leadership fencing and replica divergence
- Snapshot installation and Raft recovery
- Key-range sharding and replication factor operations
- Backups and PITR
- Partition write coalescing
Running Tests
The Kahuna.Client.Tests project holds end-to-end tests that connect to a live Kahuna cluster.
Start the Docker cluster before you run those tests:
docker compose -f docker/local.yml up -d
The client tests expect HTTPS endpoints on:
https://localhost:8082
https://localhost:8084
https://localhost:8086
Then run the tests:
dotnet test Kahuna.Client.Tests/Kahuna.Client.Tests.csproj -c Debug \
--logger "trx;LogFileName=client-tests.trx" \
--logger "console;verbosity=normal" 2>&1 | tee /tmp/kahuna-client-tests.log
When you finish, stop the cluster:
docker compose -f docker/local.yml down
The Kahuna.Server.Tests project uses embedded, in-process nodes. It does not need the Docker
cluster:
dotnet test Kahuna.Server.Tests/Kahuna.Server.Tests.csproj -c Debug \
--logger "trx;LogFileName=server-tests.trx" \
--logger "console;verbosity=normal" 2>&1 | tee /tmp/kahuna-server-tests.log
Run only one dotnet test process at a time, including across terminals. The server suite can take
about 20 minutes; use --filter for affected tests and inspect the TRX/console log for all failures from
that run. Do not run the entire solution without provisioning the Docker cluster, because it includes
the client end-to-end tests. In automation, enable your shell's pipeline failure propagation when using
tee so a failed test is not masked by a successful log write.
GitHub Actions starts the server cluster before it runs the end-to-end suite. The startup script
is scripts/run-server.sh.
Jepsen Tests
Kahuna is tested with Jepsen. Jepsen is a framework that verifies correctness of distributed systems under real-world failures: network partitions, process crashes, and clock skew.
The test suite lives at kahunakv/kahuna-jepsen. It exercises transactional guarantees, lock semantics, and replication behavior. The suite injects faults into a cluster and checks that the observed history stays consistent.
These tests check the histories produced by specific workloads and fault schedules. Passing a run is evidence for those scenarios, not proof of every concurrency, recovery or durability interleaving.
Kubernetes Operator (Alpha)
The Kahuna Kubernetes Operator automates deployment and management of Kahuna clusters on Kubernetes. It provisions clusters, scales them, and manages their lifecycle through a custom resource definition. You can run Kahuna as a native Kubernetes workload.
Note: This operator is in alpha. APIs and behavior can change between releases.
Web Dashboard
<img width="1296" height="860" alt="webui" src="https://github.com/user-attachments/assets/b05b1159-9ea5-4957-aa60-ab8e745cf17b" />
Contributing
We welcome contributions from the community. For detailed guidelines, refer to our CONTRIBUTING.md file.
License
Kahuna is licensed under the MIT License. See the LICENSE file for details.
| 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-browser1.0 is compatible. 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
- Blake3 (>= 3.0.2)
- Google.Protobuf (>= 3.29.6)
- Grpc.AspNetCore (>= 2.67.0)
- Grpc.Net.Client (>= 2.67.0)
- Kahuna.Shared (>= 1.10.6)
- Nixie (>= 1.3.2)
- Polly.Contrib.WaitAndRetry (>= 1.1.1)
- System.IO.Hashing (>= 10.0.12)
- YaccLexTools (>= 1.2.3)
-
net10.0-browser1.0
- Google.Protobuf (>= 3.29.6)
- Grpc.Net.Client (>= 2.67.0)
- Kahuna.Shared (>= 1.10.6)
- Microsoft.Extensions.ObjectPool (>= 10.0.12)
- Nixie (>= 1.3.2)
- Polly.Contrib.WaitAndRetry (>= 1.1.1)
- System.IO.Hashing (>= 10.0.12)
- YaccLexTools (>= 1.2.3)
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.10.7 | 0 | 10/2/2026 |
| 1.10.6 | 56 | 10/1/2026 |
| 1.10.5 | 72 | 9/30/2026 |
| 1.10.4 | 116 | 9/28/2026 |
| 1.10.2 | 84 | 9/28/2026 |
| 1.10.1 | 89 | 9/27/2026 |
| 1.10.0 | 79 | 9/27/2026 |
| 1.9.12 | 94 | 9/26/2026 |
| 1.9.11 | 129 | 9/25/2026 |
| 1.9.10 | 111 | 9/25/2026 |
| 1.9.9 | 89 | 9/24/2026 |
| 1.9.8 | 100 | 9/24/2026 |
| 1.9.7 | 96 | 9/23/2026 |
| 1.9.6 | 93 | 9/23/2026 |
| 1.9.5 | 100 | 9/23/2026 |
| 1.9.4 | 85 | 9/22/2026 |
| 1.9.3 | 97 | 9/21/2026 |
| 1.9.2 | 104 | 9/19/2026 |
| 1.9.1 | 95 | 9/19/2026 |
| 1.9.0 | 98 | 9/19/2026 |