SplinterDB is an embedded key-value store built for NVMe bandwidth, not for production yet
High Performance Embedded Key-Value Store
At a glance
- What is it?
- SplinterDB is a C library from VMware for applications that want a key-value store with the throughput of fast storage, documented through a USENIX ATC 2020 paper and shipped as an embeddable library with its own build, test and inspection tooling. The README itself says it is provided as-is and is not recommended for production until version 1.0.
- Who is it for?
- Adopt SplinterDB if you are building a C application that needs a key-value store inside the process rather than a client library talking to a server, and you are willing to read docs/limitations.md before you commit. Do not adopt it for a production service today, because the README states it is provided as-is and is not recommended for production until version 1.0, and the repository has no GitHub releases to pin.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A library you embed, not a server you deploy
SplinterDB is a key-value store designed for high performance on fast storage devices, and the distribution model is the first thing to understand. The README says it is a library intended to be embedded within another program, with a guide on integrating it into an application at docs/usage.md.
That is a different proposition from RocksDB or a Redis client. There is no server process, no wire protocol, no separate deployment. The store lives inside your process, the data lives in files you manage, and the API is called directly. The audience is therefore C developers who control the whole application, typically storage engines, edge services and specialised data pipelines where an embedded store removes a network hop and a failure domain.
The implementation language is C, the licence is Apache-2.0, and the project is hosted under the VMware organisation with a homepage at splinterdb.org. The repository is not archived and the last push was on 2026-10-17, though there are no GitHub releases, so there is no tag series to pin and no published changelog to read.
The design intent is stated in the project's own paper. The README points to SplinterDB: Closing the Bandwidth Gap for NVMe Key-Value Stores, by Alexander Conway, Abhishek Gupta, Vijay Chidambaram, Martin Farach-Colton, Richard P. Spillane, Amy Tai and Rob Johnson, presented at USENIX ATC 2020, pages 49 to 63. The title says the problem plainly: on NVMe-class storage, a key-value store can be limited by the bandwidth of the storage device rather than by its own logic.
The project also links a talk at the CMU Database Seminar, which is a reasonable way to understand the design before reading the code.
The build is make, with a Docker path for the toolchain
The README keeps the build instructions in docs/build.md, but the Makefile at the root shows the structure of the workflow. The help target lists the supported targets:
help::
@echo 'Usage: make [<target>]'
@echo 'Supported targets: clean all libs tools benchmarks all-tests run-tests test-results run-examples install'So there is a target for the libraries, one for the tools, one for benchmarks, several for tests, one for the examples, and an install target. The default goal is all, and the Makefile is platform aware, defaulting to PLATFORM = linux with a platform_$(PLATFORM) directory.
The source layout is conventional: SRCDIR = src, TESTS_DIR = tests with separate functional and unit subdirectories, INCDIR = include, EXAMPLES_DIR = examples and TOOLS_DIR = tools. Tests are split into functional and unit binaries, and the Makefile has a rule for building standalone unit test binaries from unit test sources while excluding test-specific common files such as btree_test_common.c.
The container path exists for teams that do not want to reproduce the toolchain locally. There are two Dockerfiles, Dockerfile.build-env and Dockerfile.run-env, and the main Dockerfile composes them. The build stage uses clang as the compiler by default, passing it through as both CC and LD:
ARG compiler=clang
ENV CC=$compiler
ENV LD=$compilerThe resulting image carries the shared library and the headers, the test binaries and the test script, and the file documents two commands:
# $ docker build -t splinterdb .
# or to run tests:
# $ docker run --rm splinterdb ./test.shOne line in that Dockerfile is worth noting for anyone planning a static build: a TODO comment says that driver_test dynamically links against the relative path lib/libsplinterdb.so and that it should be linked statically against libsplinterdb.a instead, so that the hack is not needed. The runtime image therefore needs the shared library present at the expected relative path, which constrains how you package it.
splinter_inspect reads an image without opening it for writing
The inspection utility is the tool for looking inside a database image without a running system. You build it with make tools, which is also part of make, and then run it against an image file:
build/release/bin/splinter_inspect space database.dbThe README describes the behaviour in detail, and the details are the point. The command opens the image read-only and reports its geometry, the allocated and free extents and bytes, and the reserved metadata space.
There are constraints on when you can trust the output, and the README is unusually clear about them. You must stop the database before inspecting it. Allocation totals require a cleanly closed image: when the allocation map needs recovery, the geometry is still reported but the command exits with status 1. Counts include unused pages within allocated extents, and they describe SplinterDB allocation rather than filesystem block usage, which is a distinction that matters when you are trying to explain a discrepancy against what the operating system reports. Page-type statistics are not stored in the image, so they cannot be recovered later. The --help output covers the usage and the exit statuses.
That exit status 1 case is the one to plan for. A crash or an unclean shutdown leaves an image whose allocation map needs recovery, and the tool tells you that rather than guessing. If you wire this into an operational script, treat a non-zero exit as a signal to investigate rather than a failure to ignore.
The benchmark is insert heavy and point query heavy
The benchmark target builds a concurrent random-insert and random-point-query benchmark, and the README explains what the outputs are: independently sampled throughput, per-thread rates, and optional internal task traces. The instructions in benchmarks/README.md cover the 8-inserter and 8-reader workload, time-series plots, and the configuration options.
The shape of that workload is a design statement. It measures a writer-heavy mixed workload where eight threads insert and eight threads read points concurrently, which is closer to a real ingestion service than a synthetic read benchmark. The optional internal task traces are the interesting part for an engineer: they let you see what each thread was doing, so a throughput number that looks reasonable but comes with a lot of idle time can be diagnosed rather than accepted.
The repository also ships a benchmarks directory with its own README, a scripts directory and a timing_utils.sh helper, so the measurement tooling is part of the project rather than something each user writes.
What the README does not do is publish results. The benchmark is described as something you run, with plots you generate, rather than a set of numbers the project vouches for. That is an honest arrangement for an early-stage library, and it also means any performance claim you make about SplinterDB has to come from your own run on your own hardware.
The examples are the integration guide in code form
Under examples there are five programs and a README. The set covers the cases an integrator actually hits: an introduction, iterators, an optimize path, wide values, and a custom comparison function for IPv4 address keys.
That last example is the most informative about the design. SplinterDB is a key-value store, and a key-value store that only handles byte strings forces every user with structured keys to encode and decode them, which destroys ordering and prevents range scans. A custom sort comparator for IPv4 addresses means the store can order structured keys natively, and the wide values example covers the other end of the design space, where the value is large and the key is small.
The examples directory also has its own README, which makes it the natural starting point after docs/usage.md. Together they show the API surface without you having to read the internal headers first.
For build and test infrastructure, the repository also has a default.cfg at the root, a test.sh script that the Docker image copies in and runs, a format-check.sh script and a .clang-format file. The presence of a format checker next to a contributor guide is a small signal about how changes are expected to be made.
Provided as-is, and explicitly not production recommended
The most important sentence in the README for an adopter is this: SplinterDB is provided as-is and is not recommended for use in production until version 1.0, with a pointer to docs/limitations.md for details.
That is an unusual thing for a project README to say, and it changes how you should treat the code. You are looking at a research-derived storage engine that has not yet reached the stability bar its own authors set. The limits are collected in one document, docs/limitations.md, which is the first file to read.
The licence is Apache-2.0, stated in the LICENSE file and repeated as an SPDX header in the source files, so the terms are clear and permissive for both commercial and research use.
On upkeep, the picture is mixed and worth stating precisely. The last push was on 2026-10-17, which shows recent activity, and there is a CI badge for a run-tests workflow in the .github directory. But there are no GitHub releases, so there is no version you can pin for a production build, and the README's own statement about version 1.0 implies the version numbering you would rely on for a dependency is not settled either.
The distinction that matters for a decision is between evaluating and shipping. For evaluation, the code is in good shape, the paper is published, the tooling for testing, inspecting and benchmarking is present. For shipping, the project itself tells you to wait.
Where SplinterDB is the wrong tool
The first wrong case is a service that wants a separate database server. SplinterDB is embedded, which means the store shares the process, the failure domain and the deployment lifecycle of your application. If you need independent scaling, a network boundary, or a database that a team can operate separately from the application team, an embedded library is the wrong shape, and a server based store with a client library is the right one.
The second wrong case is a language that is not C. There is no binding described anywhere in the repository, no C API wrapper project, and the examples are all C. Reaching it from another language means writing a native extension yourself and maintaining it.
The third is anything where durability and predictability must be settled rather than explored. The README says the project is not recommended for production until version 1.0 and points at a limitations document. Reading that document is the decision, and the absence of releases means there is no upgrade path with notes to read when the project changes under you.
The real alternative approach for the same goal is to use an established embedded store with a mature release history, and to spend your engineering effort on your own problem rather than on an engine that is still pre-1.0. SplinterDB earns its place when the storage behaviour itself is the differentiator, for example when you are building something whose throughput depends on NVMe characteristics that a general purpose store does not exploit. In every other case, the risk sits with you and the benefit does not.
Editorial conclusion
Adopt SplinterDB if you are building a C application that needs a key-value store inside the process rather than a client library talking to a server, and you are willing to read docs/limitations.md before you commit. Do not adopt it for a production service today, because the README states it is provided as-is and is not recommended for production until version 1.0, and the repository has no GitHub releases to pin. Before you build, read docs/build.md and docs/usage.md, run the test suite with make all-tests and the test script, and decide how you will handle the case where splinter_inspect exits with status 1 because an image needed allocation map recovery.
Frequently asked questions
What is SplinterDB and how is it deployed?
SplinterDB is a key-value store designed for high performance on fast storage devices, written in C and licensed Apache-2.0. It is a library intended to be embedded within another program, not a server, and docs/usage.md is the integration guide.
Is SplinterDB ready for production use?
The README states that it is provided as-is and is not recommended for use in production until version 1.0, and it points to docs/limitations.md for the details. The repository has no GitHub releases, so there is no tagged version to pin.
How do I build SplinterDB from source?
The build instructions are in docs/build.md, and the Makefile lists the targets clean, all, libs, tools, benchmarks, all-tests, run-tests, test-results, run-examples and install. The Dockerfile uses clang by default and offers docker build -t splinterdb . followed by docker run --rm splinterdb ./test.sh to run the tests.
What does splinter_inspect report on a database image?
It opens the image read-only and reports its geometry, the allocated and free extents and bytes, and the reserved metadata space. The database must be stopped first, allocation totals require a cleanly closed image, and when the allocation map needs recovery the geometry is still reported but the command exits with status 1.
What does the SplinterDB benchmark measure?
The make benchmarks target builds a concurrent random-insert and random-point-query benchmark with independently sampled throughput, per-thread rates and optional internal task traces. The instructions in benchmarks/README.md cover the 8-inserter and 8-reader workload, time-series plots and configuration options.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vmware-splinterdb)Was this useful?