Residiuum is a document database written in Rust. It runs inside your application as a library, or as a single server your applications connect to. You store JSON documents, relate them with a query language built for nested results, and get back the shape your application needs without an ORM or hand-written lookups. Figures here are for release 0.20.0 unless stated.
from orders
where status = "paid"
enrich customer using customers matching customer_id = _key expect exactly_one
project { _key, amount, customer { name } }
What it does
- Stores JSON documents in collections, with no schema to declare. Documents can be up to 16 MiB; large values are chunked internally.
- Builds nested results as a database operation. RQL's
enrichattaches documents from another collection, andwithinworks inside arrays. Each relationship states what it expects (exactly_one,many), so the relationship is written in the query rather than hidden in a join or an ORM. - Acknowledges a write only once it is on stable storage. That is the only mode. Write rate comes from batching and concurrency, not from relaxing durability.
- Makes every write safe to retry. Each write carries an operation identity, so sending it again after a timeout or crash returns the original result instead of writing twice.
- Commits several writes together. Atomics span any collections in a Heap, all or nothing, and only if the conditions attached to them still hold.
- Controls access with capabilities. There are no users, passwords or roles. An unforgeable token is bound to one Heap and carries a set of rights. Each Heap's master key is stored only in sealed form.
- Isolates tenants with Heaps. A Heap is an isolated database inside a store, and nothing crosses between Heaps.
- Runs inside a memory budget you set. Memory is divided into pools and accounted against the budget. An embedded store is qualified at 128 MiB and a small server at about 500 MB on one vCPU. More memory buys more cache hits, not correctness.
- Keeps a second copy if you ask it to. With a mirror root on another device, a durable write is acknowledged once it is on both, so losing either device loses no acknowledged durable write.
- Reports damage instead of hiding it. Stored data is in self-verifying frames. A read that meets damage fails as damage, never as "not found", and a scan names what it could not read and goes on.
- Recovers what survives.
doctorreports health,scrubverifies every segment and quarantines damage, andsalvagecopies out everything readable, with evidence. Backup, restore and in-place upgrade are built in.
How you use it
| Embedded | residiuum-sdk in a Rust application, in the same process |
| Server | residiuum serve, over TLS, with clients pinning the server's Ed25519 key |
| Remote clients | Rust, Node.js / TypeScript, C |
| Tools | The residiuum CLI for operations, health and recovery |
The same driver API works embedded and against a server, so an application can start embedded and move later.
Why it matters
- Less code between the database and the API. The usual path goes from rows, through joins and object hydration, to JSON. Residiuum builds the final document in the database.
- Failures become ordinary. Crashes, retries and damaged media all have defined outcomes that an application can act on, so it doesn't have to guess whether a write happened or whether a missing value was ever there.
- Small machines are a first-class target. The same engine runs in a 128 MiB process and a small cloud server, which suits edge devices, per-tenant stores and low-cost hosting.
- One thing to operate. A store is one directory, with its documents, history and indexes inside it.
Compared with others
| Residiuum | SQLite | MongoDB | PostgreSQL | |
|---|---|---|---|---|
| Runs as | Library or server | Library | Server | Server |
| Data | JSON documents | Tables, with JSON functions | BSON documents | Tables, with JSON types |
| Nested results | enrich in the query language |
Joins, assembled with JSON functions or by the application | $lookup in aggregation |
Joins, with JSON aggregation or an ORM |
| Access control | Capabilities per Heap | File permissions | Users and roles | Users and roles |
| Durability of an acknowledged write | Always synced | Set by synchronous |
Set by write concern | Synced by default, can be relaxed |
| Retry after a timeout | Built into every write | Application | Retryable writes in the driver | Application |
Measured on a 1 vCPU, 961 MiB cloud server, release 0.19.0, with every write synced on both sides and every answer checked:
- Against MongoDB 8.2 as a server, each in a 512 MiB cgroup: point reads 1.85× to 2.86×, counts on an indexed field 1.26×, with 15–76 MiB resident against 219–296 MiB.
- Against SQLite embedded, each with 128 MiB: 16 concurrent inserts 4.24× and updates 4.74× against SQLite with one transaction per write, updates 1.17× against SQLite with group commit, and a single caller's inserts 1.39×.
How it is built and checked
- Written in Rust, on an append-oriented log of immutable, self-verifying segments, with one writer per store.
- 3,516 tests, 14 fuzz targets and 243 Lean theorems in the repository, counted by the gate that runs on every push.
- Every code sample in the developer guide's tutorial chapters is compiled and run by the test suite.
- A qualification rig runs the engine on a small cloud server against SQLite and MongoDB, every night, with crash and memory tests alongside.