Why Kahuna
Give your services a shared source of truth
When multiple workers act on the same data, they need to agree on ownership, updates, and retries. Kahuna provides those building blocks—and keeps them replicated as your application grows.
One worker per job
Use leases and fencing tokens to give one worker ownership of a job or tenant.
Consistent shared state
Read current revisions and use transactional compare-and-set for workflows like rate limiting.
Safe, ordered IDs
Allocate numbers and ranges across nodes without races, with idempotent retries.
Built for 24/7 applications
Replicate persistent state through Raft and recover automatically from a leader failure. A three-replica partition can tolerate one failed replica and resume work after election while a majority remains available.
Explore failure recovery →Grow your cluster online
Add nodes to a running cluster. With replica placement and rebalancing enabled, Kahuna copies partitions to new nodes in the background, then promotes replicas once they catch up.
Explore horizontal scaling →Less coordination glue to maintain
Keep critical locks, shared state, and sequences in one consistent system, instead of maintaining coordination logic across Redis and an RDBMS. Keep your relational database for business data and queries.
Why choose Kahuna? →Custom C# logic
Run trusted C# functions inside Kahuna Script transactions for validation and business rules.
Learn about user-defined functions →Fast enough for hot paths
Single-node can reach 290k req/s for ephemeral workloads
See benchmark details →Your choice of storage
Choose RocksDB, SQLite, or memory, or run the data store and Raft log on Solarium through an external extension.
Explore the Solarium integration →Inside Kahuna
Follow one request, step by step
Choose a task, then step through it at your own pace. Each numbered message shows who sends what. These are illustrated examples of persistent operations, not a live cluster.
Both apps ask for the same lock
App A and App B both ask to lock “invoice-2048”. Their requests reach the Kahuna server in charge of that lock: its leader.
Inspect state on each node
- App node A
- Asking for lock
- App node B
- Asking for lock
- Kahuna 1
- Lock is free
- Kahuna 2
- Lock is free
- Kahuna 3
- Lock is free
Leader = server handling this key. Replicas = servers keeping copies. Highlighted cards take part in this step.
The scenario
Two apps. One lock. One winner.
Both app nodes want to process the same invoice. A lock lets only one own the job at a time.
What to remember
The lock’s owner is copied across Kahuna servers. Both apps get an answer from the same leader.
Learn about locks →Where it fits
Use it for shared ownership and control-plane work
Fewer duplicate workers, fewer stale writes, fewer homegrown coordination paths
Good fit
- Mission-critical services that run around the clock
- Growing workloads that need online cluster expansion
- Distributed locking for critical sections
- Reliable shared configuration and metadata
- Ordered ID allocation across nodes
- Custom C# functions inside transactions
- Multi-step workflows with compare-and-set
- Services that need quorum-backed coordination
- MIT-licensed Kahuna with no proprietary runtime fees
Not the target
- A general-purpose analytics database
- A document store for large unstructured datasets
- Fire-and-forget eventually consistent pipelines
- Single-node apps that do not need quorum or leader election
Example
The same code on one node or a full cluster
Start with one node on your laptop. To move to a replicated cluster, add endpoints. Pick a building block to see the client code.
using Kahuna.Client;
var client = new KahunaClient("https://localhost:8082");
await using KahunaLock jobLock = await client.GetOrCreateLock(
"jobs/invoice-2048",
expiry: TimeSpan.FromSeconds(30),
wait: TimeSpan.FromSeconds(5),
retry: TimeSpan.FromMilliseconds(200)
);
if (jobLock.IsAcquired)
{
// Pass the token to the resource you protect
await ProcessInvoice(2048, jobLock.FencingToken);
}
// The lock is released when jobLock is disposed
What this buys you
- Only one worker processes the invoice. Others wait up to 5 seconds, then give up.
- The lease expires after 30 seconds if the owner crashes, so the job never stays stuck.
- Each acquisition gets a fencing token, so the resource can reject writes from a former owner.
One node for development and tests
- Start one container and connect to one endpoint.
- Persistent data goes to disk, but there are no replicas: if the node stops, the data is unavailable until it restarts.
- Use it for local development, CI, and workloads that can accept downtime.
docker run --rm -p 8082:8082 -v kahuna-data:/data kahunakv/kahuna:latest