Lavik is built around a simple idea: use high-performance NVMe storage instead of DRAM for the data capacity tier, then optimize every layer of the I/O path until disk-resident workloads reach performance territory once reserved for in-memory services.
Keep the Redis interface. Break the memory-capacity ceiling.
Lavik is a Linux C++23 key-value server that speaks RESP2 and RESP3. It keeps a compact key index in DRAM and stores data on files, raw block devices, or SPDK NVMe namespaces, so capacity scales with storage. Networking uses kernel TCP with io_uring by default, with an optional experimental DPDK backend.
- Grow beyond RAM. Keep a compact key index in memory and values on NVMe; serve hundreds of millions of keys from files, raw devices, or SPDK storage.
- In-memory-class throughput. With 10M keys, Lavik v0.1.0 reached 1.15M GET QPS and 972K SET QPS, exceeding Redis and Valkey's peak throughput in that test. See full results.
- Keep your Redis tools. RESP2/RESP3, familiar data structures, Lua, transactions, Pub/Sub, authentication, TLS, and RDB import/export.
- Atomic transactions on primaries and replicas. Multi-key commands and
MULTI/EXECcoordinate across workers; native replication preserves transaction atomicity on replicas. See replication. - Use multiple cores and scale to a cluster. Parallel workers, replication, Redis Cluster routing, and Prometheus metrics.
Browse the performance reports for full results, test configurations, and methodology.
100× the data, comparable peak throughput—on the same 2-vCPU machine. Lavik v0.1.0 served 100M keys (95.37 GiB of values) from NVMe on a 2-vCPU / 16-GiB Azure VM, reaching 215K GET ops/s and 196K SET ops/s. Redis 8.10.2 and Valkey 9.1.2 held 1M keys in memory on the same VM; all values were 1 KiB. The chart shows throughput and p99.9 latency across connection counts.
2-vCPU test details and methodology · 16-vCPU results · Disk-backed comparisons
The Redis/Valkey comparison tested Lavik v0.1.0, Redis 8.10.2 and Valkey 9.1.2 with 10 million keys and 1 KiB values on an Azure Standard_L16aos_v4 VM.
At the same 10 million keys, Lavik surpassed both Redis and Valkey in peak GET and SET throughput, reaching 1,145,772 GET QPS and 971,950 SET QPS. GET was 12.5% faster than Redis and 18.1% faster than Valkey; SET was 2.2% and 20.3% faster, respectively.
With 1 billion keys (1TB), Lavik reached 1,069,126 GET QPS and 817,113 SET QPS—throughput comparable to Redis and Valkey holding 10 million keys in memory, with 100 times as much data.
The 1TB storage comparison tests Lavik, Dragonfly, Garnet, Apache Kvrocks, Pika and Tendis on an Azure Standard_L16aos_v4 VM with 1 billion keys and 1 KiB values. Results below use 80 connections, sorted by QPS for each command. QPS bars grow from left to right; p99.9 latency bars grow from right to left on the same row.
See also the 100-million-record YCSB comparison with Aerospike, covering workloads A/B/C/D and their tail latencies.
Start with a prebuilt package from Releases.
Packages are available for Linux x86_64 and ARM64 (aarch64). Use minimal
for kernel TCP and io_uring, or the standard package for DPDK/SPDK support.
See platform requirements below;
both variants require Linux 6.1 or newer with io_uring enabled.
For the minimal v0.1.0 release on Ubuntu 24.04:
set -e
sudo apt-get update
sudo apt-get install -y curl ca-certificates
VERSION=v0.1.0
ARCH="$(uname -m)" # x86_64 or aarch64
PACKAGE="lavik-${VERSION}-linux-${ARCH}-minimal"
RELEASE_URL="https://github.com/eloqdata/lavik/releases/download/${VERSION}"
curl -fLO "${RELEASE_URL}/${PACKAGE}.tar.gz"
curl -fLO "${RELEASE_URL}/${PACKAGE}.tar.gz.sha256"
sha256sum --check "${PACKAGE}.tar.gz.sha256"
tar -xzf "${PACKAGE}.tar.gz"
sudo install -m 0755 "${PACKAGE}/lavik" "${PACKAGE}/lavik-meta" \
"${PACKAGE}/lavik-ctl" /usr/local/bin/
lavik --versionFor DPDK/SPDK, download the package without the -minimal suffix and install
its runtime dependencies (libnuma1 and libuuid1 on Ubuntu). See the
SPDK storage guide for device setup.
Development builds are available from Nightly.
After installing, continue to Quick Start.
| Package | Backends included | x86_64 CPU target | ARM64 CPU target |
|---|---|---|---|
lavik-<version>-linux-<arch>-minimal.tar.gz |
Kernel TCP and io_uring | Compiler default (x86-64 with the CI toolchain) |
Compiler default |
lavik-<version>-linux-<arch>.tar.gz |
Kernel TCP/io_uring, DPDK networking, and SPDK storage | x86-64-v2 |
armv8-a+crc |
Nightly uses nightly as the filename version so download URLs stay stable.
The archive's VERSION and REVISION files identify the source build.
Executable names are the same in both variants: lavik, lavik-meta, and
lavik-ctl. Minimal rejects --network=dpdk and --storage=spdk with a
configuration error; --network=kernel and --storage=uring remain available.
Neither CI variant uses -march=native. On x86, the standard package requires
all x86-64-v2 features, including SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT,
CMPXCHG16B, and LAHF/SAHF in 64-bit mode. CPUs or VMs lacking any of these
features must use minimal. On ARM64, the standard package additionally
requires the CRC32 instruction extension. The requirement applies to the
package even when bypass is not selected at startup.
Prebuilt packages use these CPU targets for portability across supported
machines. To enable additional CPU optimizations available on your deployment
machine, build from source there with
./scripts/configure_release.sh, which uses -march=native, followed by
cmake --build build --parallel. Performance gains
depend on the workload and toolchain; the resulting binaries may not run on
CPUs with fewer instruction-set features.
Both variants require Linux 6.1 or newer with usable io_uring for lavik
and lavik-meta, including when DPDK/SPDK is selected. Worker initialization
requires IORING_SETUP_DEFER_TASKRUN, introduced in Linux 6.1, with no fallback
to older kernels. This is the API compatibility floor, not a tested-kernel
matrix; see Kernel requirements.
CI builds on Ubuntu 24.04; artifacts also require a compatible glibc and are
not intended for older glibc environments.
The standard package additionally needs the NUMA and UUID runtime libraries
(libnuma1 and libuuid1 on Ubuntu). It defaults to kernel TCP/io_uring;
DPDK/SPDK must be explicitly selected and provisioned. Its bundled DPDK network
drivers are TAP, ring, and virtio, so it does not support every physical NIC.
SPDK mode requires an SPDK-accessible NVMe device. Follow the
SPDK storage guide for device binding,
hugepage setup, a release-package launch command, and host restoration.
See Building and packaging for dependency setup, standard-package builds, and compatibility details.
Building locally with -march=native can improve peak QPS by enabling hardware
acceleration for CRC32C storage-integrity checks on supported CPUs, beyond the
conservative CPU targets used by portable release packages.
The standard io_uring build requires:
- Linux 6.1 or newer with io_uring enabled (
x86_64andaarch64are the release-package targets) - CMake 3.26 or newer (required by the bundled Meta dependency)
- a C++23 compiler (GCC 13+ or a recent Clang is recommended)
- Ninja, Git, and OpenSSL development headers/static libraries; GNU Make is additionally required by the optional bypass dependencies
On Ubuntu 24.04, install Git to obtain the source:
sudo apt-get update
sudo apt-get install -y gitgit clone https://github.com/eloqdata/lavik.git
cd lavik
./scripts/install_build_deps.sh
git submodule update --init bycorf third_party/mimalloc
git -C bycorf submodule update --init third_party/liburing third_party/abseil
./scripts/configure_release.sh
cmake --build build --target lavik lavik-meta lavik-ctl --parallel
sudo install -m 0755 build/lavik build/lavik-meta build/lavik-ctl /usr/local/bin/The dependency installer is shared with release CI. It supports Ubuntu 24.04
on x86_64 and ARM64; --dry-run shows the packages without installing them.
The commands above build with kernel TCP/io_uring. To include DPDK/SPDK in a
local build, run these additional commands in the same checkout:
./scripts/install_build_deps.sh --with-bypass
git -C bycorf submodule update --init third_party/spdk third_party/dpdk
git -C bycorf/third_party/spdk submodule update --init isa-l isa-l-crypto
CC=gcc-13 CXX=g++-13 ./scripts/configure_release.sh -DLAVIK_KERNEL_BYPASS=ON
cmake --build build --target lavik lavik-meta lavik-ctl --parallelLAVIK_KERNEL_BYPASS is a configure-time option. Pass it to the configure
script, not to cmake --build. Both configure scripts default it to OFF on
every run; pass -DLAVIK_KERNEL_BYPASS=ON when configuring either build tree
to enable the bypass targets and dependencies.
Local release builds use -march=native; use the packaging script below for
portable artifacts. Bypass remains an explicit runtime choice via
--network=dpdk and/or --storage=spdk.
To create a portable archive for the current architecture, run:
./scripts/package_release.shAfter installing the bypass dependencies, use
LAVIK_PACKAGE_KERNEL_BYPASS=ON ./scripts/package_release.sh for a standard
archive with DPDK/SPDK support.
The archive contains lavik, lavik-meta, lavik-ctl, LICENSE, and notices
under dist/. Without the bypass option, packaging builds the minimal variant. Main-branch
Ubuntu release CI builds both variants for
x86_64 and ARM64. Download the four archives and their SHA-256 files from
Nightly, which is
updated after successful builds of the latest main. CI artifacts are also
retained for 30 days.
For deployment beyond the basic example below:
- Quick startup tuning: generate this machine's CPU plan and start Lavik.
- Cluster deployment: launch the local Meta-managed cluster example.
For a throwaway local instance, provision a file and start the server:
mkdir -p /tmp/lavik-quickstart
fallocate -l 1G /tmp/lavik-quickstart/lavik.data
lavik \
--data-file /tmp/lavik-quickstart/lavik.dataIn another terminal, use any Redis-compatible client:
redis-cli PING
# PONG
redis-cli SET greeting "hello from Lavik"
# OK
redis-cli GET greeting
# "hello from Lavik"
redis-cli HSET user:42 name Ada language C++
redis-cli HGETALL user:42Stop the server with Ctrl-C. See Multi-Device Storage
for persistent files, raw devices, and storage expansion.
CRC generation for new data records and value/key extents is disabled by
default. Enable it with --record-crc or record-crc yes in a Redis-style
configuration file; --no-record-crc or record-crc no disables it on the next
startup. Reads always verify CRCs that are present, including records written
under a previous startup setting. Device metadata, block headers, checkpoints,
Function catalog and replication CRCs remain enabled. Without a data CRC,
structural checks still run but arbitrary payload corruption is not detected.
Lavik supports RESP2/RESP3 clients and the Redis commands described in Highlights. See the Valkey compatibility test coverage for the command suites exercised by the project. Operational differences include:
- A successful write is not a synchronous
fsyncfence; see the storage architecture before selecting failure semantics. - Redis-style configuration files may enable automatic RDB snapshots with
save <seconds> <changes>pairs;save ""disables them. Lavik keeps automatic snapshots disabled when nosavedirective is present. - Lavik Meta manages native replication and automatic failover. See the cluster deployment guide.
- A replication restart can require a full synchronization.
- Raw block and SPDK paths require exclusive device ownership.
See the contributing guide for development setup, building and testing, formatting with pre-commit, and committing a change.
Useful references:
- Documentation index
- Architecture
- Operations
- Lavik Admin: bundled browser and CLI workspace for SSH cluster setup, version selection, multi-cluster monitoring, follower resizing, and key browsing
- Prometheus metrics
- Network IRQ affinity tuning
- Performance reports
If Lavik looks useful, please star the project on GitHub. It helps more Redis users and storage engineers discover the project.
EloqData-authored code is licensed under Apache-2.0. Third-party components retain their original copyright notices and licenses; see NOTICE and the notices in each dependency.