opensourceprojects.dev

A broadsheet for software that doesn't ask for your email

Fjall uses a log-structured merge-tree under the hood, similar to RocksDB.
GitHub RepoImpressions483

Project Description

View on GitHub

An LSM-Based Key-Value Store for Rust That Puts Safety First

If you've spent any time building systems in Rust, you've probably wished for a straightforward embedded key-value store that doesn't require you to juggle unsafe code or wrap a C library. You want something that feels natural in Rust, handles concurrency without ceremony, and still delivers the performance you expect from a modern storage engine. Fjall is a log-structured merge-tree database that aims to be exactly that.

Written entirely in safe, stable Rust, Fjall gives you a thread-safe BTreeMap-like API backed by an LSM-tree architecture similar to RocksDB. It's not a standalone server—it's a library you drop into your application when you need durable, embedded storage with minimal fuss.

What It Does

Fjall is an embeddable key-value storage engine that uses a log-structured merge-tree (LSM-tree) under the hood. You interact with it through a familiar key-value interface: insert, get, remove, and iterate. Underneath, it handles all the complexity of write-ahead logging, compaction, and background maintenance automatically.

The project is organized around two core concepts: a Database that can hold multiple keyspaces (think column families from other databases), and each keyspace is its own physical LSM-tree. This means you get natural isolation between datasets while still being able to operate across them with atomic semantics. Keys are stored in lexicographic order, which is typical for key-value stores, and the README notes a practical gotcha: if you're storing integer keys like timestamps, you'll want to use big-endian encoding for predictable ordering.

Fjall supports range and prefix searching with both forward and reverse iteration—the iterators implement DoubleEndedIterator, so you can flip direction without extra complexity. It also ships with LZ4 compression by default, with optional features for serializable transactions, key-value separation for large blobs, and custom compaction filters.

Why It's Cool

What makes Fjall interesting isn't just that it works—it's how it works and what it prioritizes.

  • 100% safe Rust. This is the big one. Most LSM-tree implementations in the Rust ecosystem either wrap C libraries (RocksDB, LevelDB) or rely on unsafe for performance. Fjall commits to stable, safe Rust only. That means fewer surprises, easier auditing, and no fighting with C ABI issues.

  • Multiple keyspaces with cross-keyspace atomicity. If you've used column families in RocksDB, the concept is familiar. But Fjall exposes it through a clean Rust API where each keyspace is isolated yet you can still coordinate writes across them. This is genuinely useful for applications that need to manage different data domains without spinning up separate databases.

  • The API is just a BTreeMap. There's real value in a storage engine that doesn't make you learn a new paradigm. Insert, get, remove, iterate—it's the same mental model you already have, just backed by a durable, concurrent LSM-tree.

  • Optional features that don't clutter the core. Transactions, blob storage, compaction filters—they're all opt-in. You don't pay for what you don't use, but the capability is there when you need it.

  • Automatic background maintenance. Compaction, journaling, persistence—the engine handles this on its own. You can explicitly persist data with PersistMode::SyncAll when you need durability guarantees, but the default behavior tries to do the right thing.

How to Try It

Getting started is as simple as adding the dependency and opening a database. Here's the basic workflow from the README:

cargo add fjall

Then in your code:

use fjall::{Database, KeyspaceCreateOptions, PersistMode};

let db = Database::builder(path).open()?;
// For transactional semantics, use TxDatabase::builder

let items = db.keyspace("my_items", KeyspaceCreateOptions::default)?;

items.insert("a", "hello")?;
let bytes = items.get("a")?;
items.remove("a")?;

// Forward and reverse iteration
for kv in items.prefix("prefix") { /* ... */ }
for kv in items.range("a"..="z").rev() { /* ... */ }

// Ensure durability
db.persist(PersistMode::SyncAll)?;

The repository lives at github.com/fjall-rs/fjall, and the docs are available on docs.rs. The project requires Rust 1.90.0 or later, and there's a Discord server and Bluesky account if you want to follow development or ask questions.

Final Thoughts

Fjall isn't trying to replace every database out there. It's a focused tool for when you need an embedded key-value store in Rust and you want something that feels native, not like a foreign language binding. If you're building a Rust application that needs durable, concurrent local storage with a straightforward API, this is worth a serious look. The commitment to safe Rust is a genuine differentiator, and the multiple keyspace support with atomic semantics gives it an edge over simpler alternatives. It's the kind of project that fills a real gap in the ecosystem without overpromising.


Follow @githubprojects for more developer tools and open source projects.

Back to Projects
Project ID: 70848daf-c7d4-4dad-9ec1-ef294ef3a267Last updated: July 3, 2026 at 10:28 AM