The all-purpose KV store: blazing fast and reliably durable, scaling from tiny embedded cache to large-scale distributed database.
C++23 · LSM-tree · WAL · Multi-shard · Optional TLS · AGPL-3.0
| Category | Capability |
|---|---|
| Storage | LSM-tree (MemTable + WAL + SST), Bloom filters, leveled compaction |
| Durability | CRC32C on every record; crash-safe atomic writes (tmp+rename) |
| Large values | Automatic blob externalization for values ≥ 16 KiB |
| Compression | Per-file Zstandard (Zstd), self-describing, mixed-codec safe |
| Concurrency | Multi-shard MemTable; all engine operations fully thread-safe |
| History | Optional per-key version log; point-in-time reads; rollback |
| API servers | HTTP REST + binary TCP, both with optional TLS (mbedTLS 3.x) |
| Clustering | Standalone / Mirror / Stripe replication modes |
| ORM layer | PackedTable<&T::field>: typed tables, zero-config BinPack serialization, secondary indexes, query builder |
| Portability | Windows (MSVC) and Linux (GCC/Clang) |
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseOptional flags:
-DAKKARADB_ENABLE_TLS=ON # Enable TLS support via mbedTLS 3.x
-DAKKARADB_ENABLE_SIMD=OFF # Disable SSE4.2/AVX2
-DBUILD_SHARED_LIBS=OFF # Build as static libraryWindows: Build from within a Visual Studio / MSVC environment. Do not use plain
bashwithout initializing the MSVC toolchain.
#include <akkaradb/AkkaraDB.hpp>
auto db = AkkaraDB::open("/path/to/data", StartupMode::NORMAL);
auto& eng = db->engine();
// Raw bytes API
std::vector<uint8_t> key = {'h','e','l','l','o'};
std::vector<uint8_t> value = {'w','o','r','l','d'};
eng.put(key, value);
auto result = eng.get(key); // std::optional<std::vector<uint8_t>>
eng.remove(key);
db->close();#include <akkaradb/AkkaraDB.hpp>
// No serializer needed — BinPack handles it automatically
struct User {
uint64_t id;
std::string name;
int32_t age;
};
auto db = AkkaraDB::open("/path/to/data", StartupMode::FAST);
// Primary key is &User::id — entity and key types inferred automatically
auto users = db->table<&User::id>("users")
.index<&User::name>() // optional secondary indexes
.index<&User::age>();
users.put({1, "Alice", 30});
users.put({2, "Bob", 25});
auto alice = users.get(1ULL); // std::optional<User>
auto u = users.find_by<&User::name>("Alice"); // secondary index lookup
users.upsert(1ULL, [](User& u) { u.age++; });
// Range scan
for (const auto& [id, user] : users.scan_all()) {
// ...
}
// Query builder
auto adults = users
.query([](const User& u) { return u.age >= 18; })
.limit(100)
.to_vector();| Mode | WAL | Sync | Version History | Use case |
|---|---|---|---|---|
ULTRA_FAST |
Off | — | Off | In-memory cache, test harness |
FAST |
Async | group flush | Off | High-throughput ingestion |
NORMAL |
Async | group flush | Off | General-purpose (default) |
DURABLE |
Sync | per-write | On | Financial records, audit logs |
Fine-grained overrides are available via AkkaraDB::Options::Overrides.
put(key, value)
│
├─ [value ≥ 16 KiB] → BlobManager (.blob file, atomic write)
│ MemTable stores 20-byte BlobRef
│
└─ [value < 16 KiB] → WAL append (CRC32C, optional fdatasync)
MemTable insert (BPTree or SkipList, per-shard)
│
[shard full] → flush to SST → compaction
Read path: MemTable → SSTManager (L0 → L6, bloom filter + sparse index).
AkkaraDB::Options opts;
opts.data_dir = "/var/lib/akkaradb";
opts.mode = StartupMode::FAST;
// Fine-tune
opts.overrides.blob_threshold_bytes = 32 * 1024; // 32 KiB externalize threshold
opts.overrides.sst_codec = Codec::Zstd; // compress SST files
opts.overrides.blob_codec = Codec::Zstd; // compress blob files
opts.overrides.memtable_threshold_per_shard = 128ULL << 20; // 128 MiB/shard
opts.overrides.sst_bloom_bits_per_key = 10; // ~1% false-positive
auto db = AkkaraDB::open(opts);For the full configuration reference, see SPEC.md §14.
// Enable via engine options
AkkEngineOptions eng_opts;
eng_opts.api.http_enabled = true; // REST on :8080
eng_opts.api.tcp_enabled = true; // Binary protocol on :9090
// Optional TLS (requires AKKARADB_ENABLE_TLS=ON at build time)
eng_opts.api.tls.enabled = true;
eng_opts.api.tls.cert_path = "/etc/akkaradb/server.crt";
eng_opts.api.tls.key_path = "/etc/akkaradb/server.key";
eng_opts.api.tls.ca_path = "/etc/akkaradb/ca.crt"; // mTLS
eng_opts.api.tls.verify_peer = true; // mTLSHTTP endpoints: GET/POST/DELETE /v1/get|put|remove?key=<percent-encoded>
Binary protocol: 16-byte framed request + 13-byte framed response. CRC32C on payload.
Enabled in DURABLE mode or via opts.overrides.version_log_enabled = true.
// Point-in-time read
auto entry = eng.get_at(key, target_seq);
// Full write history for a key
auto hist = eng.history(key); // vector<VersionEntry>
// Rollback all keys to a prior state
eng.rollback_to(checkpoint_seq);
// Rollback a single key
eng.rollback_key(key, checkpoint_seq);| Library | Version | License | Notes |
|---|---|---|---|
| Zstandard | 1.5.6 | BSD | Always included (static) |
| Boost.PFR | boost-1.84.0 | BSL-1.0 | Header-only; aggregate struct reflection for BinPack |
| mbedTLS | 3.6.2 | Apache-2.0 | Optional (-DAKKARADB_ENABLE_TLS=ON) |
All dependencies are fetched automatically via CMake FetchContent.
{data_dir}/
├── wal/ Write-Ahead Log segments (.akwal)
├── sstable/
│ ├── L0/ Level-0 SST files (.aksst)
│ ├── L1/ … L6/
├── blobs/
│ ├── 00/ … ff/ Large-value blob files (.blob)
├── history.akvlog Version log (if enabled)
├── manifest.akmf SST lifecycle manifest
├── cluster.akcc Cluster topology (if enabled)
└── node.id Persistent node identity
- MemTable put: ~100–200 ns (arena alloc + BPTree insert, no WAL in
ULTRA_FAST) - WAL enqueue (Async): ~10–20 ns (double-buffered arena, fire-and-forget)
- WAL enqueue (Sync): blocked until
fdatasynccompletes - SST point read: ~1–5 µs (bloom check + sparse index seek + ≤128 record scan)
- Blob read: disk I/O latency + optional Zstd decompression
- Shard selection:
fp64 & mask— ~1 ns, branchless
For benchmark setup and results, see benchmarks/benchmark.cpp.
AkkaraDB is free software licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). Copyright © 2026 Swift Storm Studio.
See LICENSE for the full license text.