Persistence is the layer everybody depends on — so it should be the layer nobody has to fear.
Today we’re releasing OxiStore 0.2.0 — the COOLJAPAN Pure Rust low-level storage layer: embedded key-value, columnar in-memory & on-disk, and a blob storage abstraction spanning local filesystem and the major clouds.
No RocksDB. No LevelDB. No LMDB. No FFI. No -sys crates. Just a clean, memory-safe storage foundation that compiles in a fresh rust:slim container with no apt-get install and no C toolchain in sight.
Why OxiStore
The Rust ecosystem has a quiet dependency problem hiding at the bottom of the stack. The moment a project needs durable storage “without SQL overhead,” it reaches for rocksdb (C++), lmdb-rkv-sys (C), or leveldb-sys (C++). Suddenly your pure-Rust crate carries a native build dependency, a system library, and a cargo build that fails on any machine missing librocksdb-dev.
Across COOLJAPAN we kept hitting this same wall. oxirs needs a triplestore. oxionnx needs a model cache. oximedia needs an asset DB. oxirag needs a vector-store backend. oxify needs session storage. Each one wanted a fast embedded KV engine — and each one was being pulled toward a C/C++ engine and an FFI boundary.
OxiStore exists so none of them ever have to. It is deliberately the layer below SQL: OxiSQL sits on top when you want queries; OxiStore is the raw key-value, columnar, and blob substrate beneath it. The non-negotiable design goal was simple — cargo build --workspace --no-default-features should produce a working KV store with no C toolchain. cargo tree --workspace --no-default-features shows zero *-sys crates. That’s the whole point.
What we built
OxiStore is a 13-crate workspace, each piece doing one job well and composing through a small set of core traits.
1. The core abstraction (oxistore-core)
At the center are the KvStore, KvTxn, and KvSnapshot traits, plus StoreError, TTL support, compare-and-swap (CAS), batch operations, and a TypedKvStore for working with structured values instead of raw bytes. Every backend implements this same surface, so swapping engines is a configuration change, not a rewrite.
2. Three pluggable KV engines OxiStore doesn’t pick one storage architecture and force it on you — it gives you the right tool for the workload:
oxistore-kv-redb— the default engine, a redb B-tree backend: a single-file, ACID store. This is the LMDB/LevelDB replacement for read-friendly, transactional workloads.oxistore-kv-sled— the sled embedded backend, with named trees, merge operators, and watch-prefix subscriptions.oxistore-kv-fjall— a fjall LSM-tree backend tuned for write-heavy workloads, with cross-keyspace snapshots. This is the direct stand-in for RocksDB.
B-tree when you read more than you write, LSM-tree when you write more than you read — same trait, your choice.
3. Columnar storage (oxistore-columnar)
Parquet/Arrow columnar storage with predicate pushdown, a streaming writer, and OxiARC codecs — in-memory analytics format and on-disk persistence, without dragging in a C-based Parquet stack.
4. Cache primitives (oxistore-cache)
A real eviction toolkit: LRU, ARC, LFU, and W-TinyLFU policies, per-entry TTL, and write-through / write-back adapters so a cache can sit transparently in front of any KvStore.
5. A blob storage abstraction (oxistore-blob + cloud backends)
A BlobStore async trait with content-addressable, streaming semantics. Local filesystem and in-memory backends ship in the core crate; three cloud backends fill out the rest, every one of them Pure Rust:
oxistore-blob-s3— S3 via AWS SigV4, signed withoxihttp-client+oxitls(noring).oxistore-blob-azure— Azure Blob Storage via HMAC-SHA256 Shared Key.oxistore-blob-gcs— Google Cloud Storage via OAuth2 RS256 JWT.
6. Encryption & compression (oxistore-encrypt, oxistore-compress)
Cell-level AEAD encryption-at-rest using XChaCha20-Poly1305 via OxiCrypto, exposed as an EncryptedKv<T, K, A> decorator that wraps any backend. Compression is handled by an OxiARC DEFLATE codec bridge for Parquet — never flate2, zstd, brotli, or miniz_oxide.
7. The facade (oxistore)
Tying it together is a single front-door crate offering open, open_with, and open_in_memory, each returning a Box<dyn KvStore>. You don’t have to know which engine you’re using to start using it.
Getting Started
Add the facade crate:
cargo add oxistore
Or in Cargo.toml:
[dependencies]
oxistore = "0.2.0"
Basic key-value operations — open a store, put, get:
use oxistore::{open, KvStore};
let store = open("/tmp/my-store").expect("open failed");
store.put(b"hello", b"world").expect("put failed");
let val = store.get(b"hello").expect("get failed");
assert_eq!(val.as_deref(), Some(b"world".as_ref()));
By default you get the redb B-tree backend — single-file, ACID, no native dependencies.
Highlights
- Three KV engines, one trait — redb B-tree (default), sled, and fjall LSM-tree, all behind
KvStore/KvTxn/KvSnapshot. - Transactions, snapshots, TTL, and CAS baked into the core abstraction.
- Typed access via
TypedKvStorefor structured values, plus batch operations. - Columnar Parquet/Arrow with predicate pushdown and a streaming writer.
- Production cache policies — LRU, ARC, LFU, W-TinyLFU with write-through/write-back adapters.
- Blob storage everywhere — local fs, in-memory, S3, Azure, and GCS through one async
BlobStoretrait. - Encryption-at-rest via cell-level XChaCha20-Poly1305 (OxiCrypto).
- Pure Rust guarantee —
cargo tree --no-default-featuresshows zero*-syscrates; nolibrocksdb-dev, noliblmdb-dev, no C toolchain.
Tips
- Pick your engine by workload. Default
kv-redb(B-tree) is ideal for read-heavy, transactional data. Enable thekv-fjallfeature for write-heavy ingestion (LSM-tree). Enablekv-sledwhen you want named trees, merge operators, or watch-prefix. - Stay minimal, opt in as you go. Only
kv-redbis on by default. Turn oncolumnar,cache,blob,encrypt, andcompressfeatures individually so you ship exactly the storage surface you use. - Start in memory. Reach for
open_in_memoryin tests and ephemeral workloads — sameBox<dyn KvStore>, no files on disk. - Encrypt without rewriting. The
encryptfeature gives you theEncryptedKv<T, K, A>decorator: wrap any existing backend for cell-level AEAD rather than reworking your storage code. - Cloud blobs are Pure Rust too. S3/Azure/GCS backends sign over
oxihttp-client+oxitls(rustls + rustcrypto), neverring— so cloud persistence stays inside the sovereign stack. - Compression is OxiARC. The Parquet codec bridge uses
oxiarc-deflate; you never needflate2,zstd, orbrotlito read or write columnar data.
Part of the COOLJAPAN ecosystem
OxiStore is part of NoFFI — the COOLJAPAN initiative to replace every C/C++/Fortran/-sys FFI dependency in the Rust world with a clean, memory-safe, 100% Pure Rust implementation. Default features are 100% Pure Rust: a single static binary, no system libraries, no build-time C toolchain, WASM-friendly. OxiStore’s specific job is retiring librocksdb-sys, lmdb-sys, and leveldb-sys.
It sits among siblings it both leans on and serves. It depends on oxicrypto (encryption-at-rest), oxiarc (compression + Parquet codec), oxitls (cloud blob TLS — rustls + rustcrypto, never ring), and oxihttp (cloud HTTP client). In turn it underpins oxisql (SQL atop KV + columnar), oxirs (RDF triplestore), oxionnx (model cache), oxirag (vector embeddings persistence), oximedia (asset blob storage), and oxify (session and token KV).
Repository: https://github.com/cool-japan/oxistore
Star the repo ⭐ if you want a Rust ecosystem where the storage layer at the very bottom is finally sovereign.
Pure Rust storage — sovereign, safe, and FFI-free.
— KitaSan at COOLJAPAN OÜ June 23, 2026