UStore: a multi-modal transactional database in C++
Multi-Modal Database replacing MongoDB, Neo4J, and Elastic with 1 faster ACID solution, with NetworkX and Pandas interfaces, and bindings for C 99, C++ 17, Python 3, Java, GoLang 🗄️
At a glance
- What is it?
- UStore is a C++ database that puts several storage models behind one API: blobs, documents, graphs and vectors over RocksDB, LevelDB, UDisk, UCSet or other backends, with ACID transactions, Apache Arrow Flight RPC, and Python, C, C++, Go and Java drivers. It is Apache-2.0 licensed, but its release tags stopped in 2023.
- Who is it for?
- Adopt UStore if you are building a data platform for machine learning workloads and want one engine that holds vectors, documents and graph structure in the same store with transactions across them, reachable from Python through the Arrow Flight interface.
- 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 38 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
One store for several data models, and what replaces what
The repository description is a claim worth taking apart, because it defines the whole project. UStore is described as a multi-modal database that replaces MongoDB, Neo4J and Elastic with one faster ACID solution, with NetworkX and Pandas interfaces and bindings for C 99, C++ 17, Python 3, Java and Go. The README states the same structure in a more careful way. The project is a modular, multi-modal, transactional database for artificial intelligence and semantic search. Modularity refers to the storage engine, and the list is explicit: it supports RocksDB, LevelDB, UDisk, UCSet and other backends, and the last of those is a link to a directory of further backends in the repository. Multi-modal refers to what can be stored: blobs, documents and graphs, with features and texts marked as coming. Transactional refers to the ACID guarantees, which the README breaks into separate sections for atomicity, consistency, isolation and durability. So the project is not a graph database with vectors bolted on, and it is not a document store with a search index. It is one store with a layer that lets different data shapes live in the same database, and the audience is teams whose machine learning pipelines keep bouncing between three separate systems that cannot be updated in one transaction.
Engines chosen at compile time, modalities chosen at runtime
The engine question is settled when the library is built, and this is worth understanding before you try the library in Python. The Python setup script defines a CMake build extension and passes a set of flags, among them -DUSTORE_BUILD_ENGINE_UCSET=1, -DUSTORE_BUILD_ENGINE_LEVELDB=1 and -DUSTORE_BUILD_ENGINE_ROCKSDB=1, along with -DUSTORE_BUILD_API_FLIGHT_CLIENT=1 and -DUSTORE_BUILD_SDK_PYTHON=1. The same script sets the build parallelism to half the number of CPU cores, since the underlying build is CMake driven and parallel. The consequence is that the choice between RocksDB, LevelDB, UCSet and the rest is a build time decision, and the Python wheel is published with a specific set of them compiled in, not all of them available at runtime. The modality question is different, because the same database can hold several kinds of value at once, and the README's map of the documentation shows a section per modality, with blobs, documents, graphs and vectors as the four listed. The engine underneath is a key value store, and the higher layers give it structure. The related repositories give a sense of the ecosystem: UKV for the key value layer, USearch for the vector search integration, and UForm for the embedding side, which is what the vector-search and semantic-search parts of the positioning rest on.
The Python surface looks like a dict, a table and a graph
The quickstart is the clearest statement of the design, because the API is deliberately small. Installation is a pip install of the ukv package, and the first example creates an in-memory embedded transactional database and writes one entry into a collection called main.
from ukv import umem
db = umem.DataBase()
db.main[42] = 'Hi'The README then shows that moving the same data to disk is a one line change, by importing the rocksdb module instead and passing a folder path.
from ukv import rocksdb
db = rocksdb.DataBase('/some-folder/')And connecting to a remote UStore server is equally short, using the flight client, because UStore comes with an Apache Arrow Flight RPC interface.
from ukv import flight_client
db = flight_client.DataBase('grpc://0.0.0.0:38709')The graph and table interfaces are where the multi-modal claim becomes concrete, and they are the two familiar Python APIs borrowed here. A collection exposes a table, which takes a Pandas DataFrame, and a graph, which takes edges the way NetworkX does.
db = rocksdb.DataBase()
users_table = db['users'].table
users_table.merge(pd.DataFrame([
{'id': 1, 'name': 'Lex', 'lastname': 'Fridman'},
{'id': 2, 'name': 'Joe', 'lastname': 'Rogan'},
]))
friends_graph = db['friends'].graph
friends_graph.add_edge(1, 2)The same call signature then addresses what the README describes as hundreds of terabytes of data placed somewhere in persistent memory on a remote machine, which is the point of the abstraction and also its risk, because the call does not look like something that touches a network.
Transactions that span a table and a graph
The consistency story is short and concrete. The README asks the question directly, whether someone else is concurrently updating those collections, and answers it with a bundle your operations to guarantee consistency, shown as a transaction context manager.
db = rocksdb.DataBase()
with db.transact() as txn:
txn['users'].table.merge(...)
txn['friends'].graph.add_edge(1, 2)The interesting property is that the two writes in that block touch different modalities. A row in a table and an edge in a graph are committed or aborted together, and that is the capability the positioning rests on, because a recommendation pipeline that updates a user profile table and a similarity graph in two systems can leave the two inconsistent. The documentation structure backs up the claim rather than just asserting it, with separate sections for atomicity, consistency, isolation and durability under the transactions heading, and a further section on configuration covering key sizes and value sizes. The engine underneath is a key value store with a familiar transaction model, so the ACID story is a property of the layer rather than something exotic. The limitation to keep in mind is that transactions are scoped to one database instance, so a multi-process or multi-machine deployment still has to decide how it handles the coordination the API does not cover.
Arrow Flight as the way out of the process
The Apache Arrow Flight interface is the architectural choice that makes UStore interesting rather than merely unusual. Instead of inventing a wire protocol, the project uses an existing columnar RPC standard, and the README lists what that buys: serving the data via Arrow Flight to Spark, Kafka or PyTorch. The Python client shown earlier is a Flight client pointing at a gRPC address, and the port in that example is the one you would use in a deployment. For a machine learning platform this is the point of the whole design, because the consumer of a vector index or an embedding table is usually a Python training loop, a Spark job or a Kafka consumer, and all three speak Arrow. The documentation also names the AI use cases as their own section, and the repository carries a JavaScript directory and a Rust directory alongside the Python, Java, C and C++ bindings, so the intent is a database that a data platform can sit in the middle of rather than an embedded library for one language. The counterpoint is that Arrow Flight is still a moving target, and a dependency on it ties the server side to that ecosystem's release cycle.
Building the C++ core with CMake, Conan and multi-arch Docker
This is a C++ project with a Python package on top, and the build tooling shows it. The Python packaging uses setuptools with a custom CMake extension, and the build requirements list includes setuptools, wheel, cmake at 3.22 or newer, pybind11-stubgen and a pinned pyarrow, which is the tool that generates the Python stubs from the C++ headers. The repository also carries a conanfile.py for the C++ dependencies, a CMakeLists.txt, a build.gradle and a pom.xml for the Java side, and a setup.py that reads the version from a VERSION file at the root. The container build is where the native dependencies get assembled. The Dockerfile starts from ubuntu 22.04, installs the toolchain, pins conan at 1.60.1, and then downloads a prebuilt dependency archive from the ustore-deps releases, choosing the x86 or arm archive depending on the target platform, before installing it into the Conan cache.
RUN conan profile new --detect default && \
conan profile update settings.compiler.libcxx=libstdc++11 default && \
tar -xzf $ARCHIVE -C ~/.conanThe same pattern appears in the Python wheel build configuration, which fetches the matching archive for the architecture it is building for. The practical implication for an adopter is that you need either a toolchain that can build the C++ core or a container image, and the CI setup pins a specific compiler generation, with the Conan profile set to version 11 in the Python build configuration. The repository also carries a devcontainer definition, a Dockerfile, and directories for tests, benchmarks and tools, plus a CHANGELOG and a CITATION file for academic use.
A live branch with stale release tags
The maintenance picture is the part to weigh carefully, and it needs two numbers rather than one. The repository is not archived, and the last push was on 2026-09-15, so the code is being worked on. The release tags, however, are much older, with v0.13.12 dated 2023-08-18 and v0.4.2327 from 2023-01-14, and the project publishes no GitHub releases to bridge the gap. A version number that increments on every build, which is what the 0.4.2327 tag suggests, is a nightly build counter rather than a release scheme, and that has a practical effect: there is no version to pin in a production dependency, and the only way to know what you have is to look at the commit. The licence is Apache-2.0, which is the permissive choice and a good fit for a project that a company may want to embed, fork or redistribute, subject to the usual notice obligations. The documentation is hosted on the project pages and there is a Discord and a blog, so the community channels are active even if the tags are not. The honest summary is that this is a project with a moving codebase, an active community and no published release cadence, which suits research and evaluation use far better than it suits a production dependency with a support contract.
Editorial conclusion
Adopt UStore if you are building a data platform for machine learning workloads and want one engine that holds vectors, documents and graph structure in the same store with transactions across them, reachable from Python through the Arrow Flight interface. It does not fit a team that needs a battle tested production database with a release cadence and an ecosystem, because the last tagged releases are from 2023 even though the branch is still receiving pushes, and it does not fit a team that wants to avoid compiling native dependencies. Before you commit, read the containers and configuration sections of the documentation, and check the engine build flags in the Python setup script, because the storage backend is chosen at compile time rather than at runtime.
Frequently asked questions
What is UStore and what does it aim to replace?
It is a multi-modal transactional database written in C++ that the description presents as a replacement for MongoDB, Neo4J and Elastic with one ACID solution. The README frames it as a modular, multi-modal, transactional database for artificial intelligence and semantic search.
Which storage engines can UStore use?
The README lists RocksDB, LevelDB, UDisk, UCSet and other backends, and the engine is chosen at build time rather than at runtime, with the Python setup script passing CMake flags such as -DUSTORE_BUILD_ENGINE_ROCKSDB=1 and -DUSTORE_BUILD_ENGINE_LEVELDB=1.
How do I install and use UStore from Python?
Install the ukv package with pip, then import one of the backends. umem gives an in-memory embedded database, rocksdb gives an on-disk one by passing a folder path, and flight_client connects to a remote server over Arrow Flight RPC with an address such as grpc://0.0.0.0:38709.
What can a UStore transaction cover?
The transact context manager bundles operations for consistency, and the example in the README merges into a table and adds an edge to a graph inside the same transaction, so writes across different data modalities commit together.
Which language bindings does UStore provide?
The README lists drivers for Python, C, C++ 17, Go and Java, and the repository carries python, java, javascript and rust directories. Packages are offered through PyPI, CMake and Docker Hub.
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/unum-cloud-ustore)Was this useful?