a maintained fork of CozoDB · v0.8.5

embedded Datalog.
performant graphs.
a substrate for machine memory.

mnestic is a transactional relational–graph–vector database that speaks Datalog, the same engine that called itself “the hippocampus for AI,” now actively maintained and tuned as the recall layer for agents.

MPL-2.0 · Rust · RocksDB / SQLite / in-memory backends

recall.cozo — graph ∩ vector, one query
1# every memory reachable from a seed, then the 12 nearest by meaning
2recall[to] := *recalls{ from: $seed, to }
3recall[to] := recall[via], *recalls{ from: via, to }
4 
5?[memory, dist] :=
6 recall[memory],
7 ~memory:embedding{ memory |
8 query: $cue, k: 12, ef: 80, bind_distance: dist
9 }
10:order dist
11:limit 12

Why a fork

CozoDB went quiet after December 2024. The design is too good to let drift. So we forked it, openly, under MPL-2.0, and pointed it at one job: being the memory an agent can trust. Every divergence is documented, every original copyright preserved.

The engine you inherit

01

Datalog, not SQL

Queries compose piece by piece. Recursion is first-class, and runs faster than the SQL equivalent. A safe subset of aggregations is allowed inside recursion.

02

Relational · graph · vector

One engine, one model. The relational algebra handles graph structure implicit several levels deep, with no shoehorning your data into a labelled-property graph.

03

Embeddable like SQLite

Runs in-process (no server, no setup), yet scales to large data and high concurrency, and can also run client-server when you want it to.

04

Vector search (HNSW)

Disk-resident HNSW indices unify with Datalog: search by meaning inside a recursive query, filter with the rest of your rules, all in one pass.

05

Full-text & near-dup

Built-in full-text search and MinHash-LSH for near-duplicate detection: the keyword and dedup legs of retrieval, native to the engine.

06

Time travel

Relations can carry validity time. Query the graph as it was at any historical point: memory you can rewind, not just overwrite.

Built to be fast

upstream figures · 2020 Mac mini · RocksDB backend

100K+
QPS

mixed read / write / update transactions

250K+
QPS

read-only queries

<1 ms
2-hop

on a 1.6M-vertex, 31M-edge graph

~50 MB
peak RAM

at OLTP load

Backup ≈ 1M rows/s · restore ≈ 400K rows/s · PageRank on 1.6M vertices ≈ 30 s. mnestic keeps these and adds the recall-focused wins below.

What mnestic adds

Faster, safer, and built for recall.

The query language and semantics are unchanged. What changed is the stuff that bites you in production (lock contention, full scans, seven-rule retrieval pipelines) and the things agents actually need.

0.8.1–0.8.4

Three-way recall in one call

Vector similarity, keyword match, and graph proximity — the three signals behind “what should I recall right now” — fuse in a single typed call, ranked by Reciprocal Rank Fusion and diversified with MMR. It used to take about seven hand-written Datalog rules, and every result can now tell you which signals surfaced it.

all three signals, one transaction · ~4× faster than stitching it by hand

0.8.1–0.8.5

Index builds that never block reads

Building a vector (HNSW) or full-text index used to lock the table and stall every reader until it finished. Now the build happens off to the side while reads keep flowing the whole time — and the build itself is up to 15× faster.

40k vectors indexed in ~19 s · 90k reads served mid-build

0.8.3

Full-text search that ranks correctly

Keyword search now scores with Okapi BM25 — the ranking standard behind modern search engines — instead of raw term counts. The keyword half of hybrid recall actually surfaces the right passages.

fused recall climbs 0.75 → 0.954 on a 40k-chunk corpus

0.8.5

Reads that don’t wait on writers

Read-only queries now read through a plain snapshot instead of opening a transaction, so a busy writer can never block a reader. For an agent recalling while it ingests, that means steady, predictable latency.

keyed point reads −16% p50, −19% p99

0.8.0

Key lookups skip the full scan

Filtering a stored relation by an exact key now compiles to a direct keyed seek instead of scanning every row — the difference between a constant-time lookup and a full table walk on your hottest queries.

~28× faster single-row primary-key lookups

0.8.0

Time-ordered IDs for memory streams

rand_ulid() generates sortable, time-ordered identifiers — ideal for append-only memory you scan by recency, with the creation time recoverable straight from the key.

lexicographically sortable · time-ordered scans

The headline feature

Hybrid retrieval,
one typed call.

Vector similarity, keyword match, and graph proximity are three different signals about “what should I remember right now.” As of 0.8.3 mnestic fuses all three natively: a typed graph leg joins the vector and keyword legs in one call, combined by Reciprocal Rank Fusion and de-duplicated by Maximal Marginal Relevance.

  • Graph proximity is a typed GraphLeg: bounded-hop, ranked by min distance
  • Query vector, text & seeds passed as params, never string-interpolated
  • One call, one transaction; generated CozoScript inspectable via hybrid_search_script
hybrid recall — RRF + MMR in one call
1use cozo::{DbInstance, GraphLeg, HybridSearch, MmrParams};
2 
3// One typed call: HNSW + FTS + graph proximity, fused natively
4// with Reciprocal Rank Fusion, then MMR-diversified.
5let recalls = db.hybrid_search(&HybridSearch {
6 relation: "memory".into(),
7 vector_index: "embedding".into(),
8 query_vector: cue, // Vec<f32> from your embedder
9 vector_k: 24,
10 ef: 80,
11 fts_index: "summary_fts".into(),
12 query_text: "pricing decision",
13 fts_k: 24,
14 // graph leg: expand 2 hops from a seed over *recalls,
15 // rank by min hop distance — fused in the same call.
16 graph_legs: vec![GraphLeg {
17 edge_relation: "recalls".into(),
18 seeds: vec![seed.into()],
19 max_hops: 2,
20 ..GraphLeg::default()
21 }],
22 rrf_k: 60.0,
23 mmr: Some(MmrParams { lambda: 0.5, k: 12, embedding_col: "embedding".into() }),
24 ..HybridSearch::default()
25})?;
Hybrid recall, measured

One engine for all three signals.

The task is fusing vector, keyword, and graph proximity into one ranking. Raw latency isn't what separates the field at this scale. Three structural things are, and mnestic is the only embedded engine here that gets all three right.

01

It has a graph signal at all

Graph proximity is correlated but distinct from vector and keyword: drop it and you lose recall the other two can't recover. It's the single largest effect in the run, with the graph-less engines (LanceDB) landing far below. This is why graph-augmented retrieval exists.

02

One store, one call, no glue

mnestic serves all three signals from one embedded store and fuses them in a single transactional call. SQLite, DuckDB and Kuzu keep them in one process but fuse in app code (three queries + a hand-rolled RRF); LanceDB fuses natively but needs a second system for graph.

03

Read-your-writes on every signal

An agent writes a memory and must recall it immediately. mnestic's indexes update in the same transaction, giving 100% fused read-your-writes. DuckDB's full-text index is a build-time snapshot: a new memory is unsearchable by keyword (0%) until a rebuild. A static-corpus drag race hides this entirely.

On quality, mnestic hits recall@10 of 0.954, level with DuckDB's 0.957 and far above the graph-less LanceDB (0.501). It's the only engine here that fuses all three signals in one transaction:

Enginerecall@10SignalsFusionFused read-your-writes
mnestic0.954vec · FTS · graphnative · one call100%
duckdb 1.5.30.957vec · FTS · graphapp-side glue0% full-text †
sqlite 0.1.91.000*vec · FTS · graphapp-side glue100%
lancedb 0.330.501vec · FTSnative · no graphn/a — no graph

The native call is the fast path

mnestic's one-call 3-way fusion runs at ~42 ms p50, faster than DuckDB's decomposed path and about 4× faster than hand-decomposing it yourself. It's the only engine here that fuses three signals in a single call; LanceDB's native call covers just two.

Latency, in context

mnestic isn't the lowest absolute latency at this scale, but the numbers hold up off the test wheel. Re-measured on the RocksDB backend it actually runs, with real sentence-transformer embeddings, the decomposed path's tail falls (p99 181 ms vs 258 on the wheel) and the native 3-way call stays around 40 ms. What holds is quality and capability: matching the best indexed engine while fusing a signal the others can't.

† DuckDB's full-text index is a build-time snapshot — its fused read-your-writes is 99% overall but 0% for the keyword leg until a rebuild. Source: the mnestic-benchmarks hybrid suite, summarized in the 0.8.5 changelog. Small scale (40k chunks, 10k entities, 50k edges, dim 384) · 1,000 queries, k=10, 2-hop graph · 2026-05-31 · macOS arm64. Numbers are hardware-specific. Recall@10 is the synthetic text-derived-embedding run on the SQLite-backed wheel, where the vector signal is meaningful by construction; latency is additionally validated on the RocksDB backend with real sentence-transformer embeddings. *SQLite's recall reflects an exact brute-force KNN scan (no ANN index), not a like-for-like indexed search. Kuzu did not complete (extension host offline since its Oct-2025 archival).

Add it to your project

Cargo.toml — the importable name stays cozo
1# default = in-memory + SQLite backends
2cargo add mnestic
3 
4# or, with the RocksDB backend:
5# mnestic = { version = "0.8", features = ["storage-rocksdb"] }
main.rs
1use cozo::DbInstance;
2 
3let db = DbInstance::new("mem", "", "")?;
4db.run_default("?[x] := x in [1, 2, 3]")?;
Python — with LangChain & LlamaIndex adapters
1pip install mnestic # the engine (abi3 wheels)
2pip install langchain-mnestic # LangChain vector store
3pip install llama-index-vector-stores-mnestic

Naming, on purpose

The published crate is mnestic, but the importable library name stays cozo. Every use cozo::… in your existing code, and in downstream crates, keeps working unchanged. A drop-in, not a rewrite.

Credit where it’s due

mnestic is not the official CozoDB and is not affiliated with or endorsed by its authors. All credit for the original design belongs to Ziyang Hu and the Cozo Project Authors.