LatticeDB

2026-09-04 · page · source ↗ · source summary

LatticeDB is an embedded, single-file property-graph database that puts graph traversal, HNSW vector search, and BM25 full-text search behind one Cypher-based query layer. Written in Zig (~66K lines, zero runtime dependencies, MIT, v0.15.0), it is built for relationship-heavy single-machine workloads — Graph RAG, agent memory, and local knowledge tools — and is unusually honest that it is a single-writer embedded engine, not a distributed database. Its most interesting idea is that an event log (durable streams plus a graph changefeed) is a first-class database primitive sharing the same WAL path as graph writes, not a bolted-on consumer.


Architecture

LatticeDB is a classic layered storage engine in the ARIES — Write-Ahead Logging Recovery tradition, rebuilt around one uniform primitive: everything is a 4 KB page. B+Tree nodes, WAL frames, the file header, and freelist entries are all pages, so there is one caching layer, one I/O path, and one checksum format (docs/00_introduction.md).

The stack, bottom-up (src/storage/): a VFS abstraction (vfs.zig, with an in-memory memory_vfs.zig), a page manager with checksums and freelist (page_manager.zig), a buffer pool with per-page reader-writer latches and a clock eviction policy (buffer_pool.zig), a B+Tree (btree.zig, 3.1K lines) with explicit overflow pages for large values, a WAL (wal.zig), a checkpointer, and an ARIES-style recovery manager (recovery.zig). Above it sits a transaction manager (transaction/manager.zig) that writes records with prev_lsn back-pointers for undo chaining, plus MVCC machinery (transaction/mvcc.zig).

The graph is not a bespoke storage format — it is several B+Trees decomposed by access pattern (docs/09_graph_storage.md): a two-way symbol table for string interning, a node store keyed by u64 ID, an edge store that writes two traversal keys ((source, dir, type, target, edge_id) outgoing and (target, dir, type, source, edge_id) incoming, big-endian so range scans are contiguous) plus a separate edge-ID index holding the payload once, a label index, and equality property indexes. Stable edge IDs give parallel edges first-class identity. The query engine is a Volcano iterator model (src/query/operators/, docs/12_query_execution.md): lexer → parser → semantic analyzer → planner → a pull-based operator tree over fixed 16-slot rows allocated from an arena.

Key Techniques

Design Decisions

Comparison Notes

AntFly is the same hybrid graph+vector+BM25 thesis executed at the opposite pole: a distributed multi-Raft system with write-time AI enrichment and Go/Zig split, where LatticeDB is an embedded single-file library with no consensus, no cluster, and no generated embeddings. They share the Zig hot path and the "one engine, three search modes" vision.

Just Brute Force Your Embeddings argues most teams don't need an ANN index; LatticeDB is the rung above brute force — its claimed 0.83 ms at 1M vectors with 100% recall is competitive with FAISS and Weaviate — but it only matters once you also want graph traversal and BM25 in the same query, not just vectors. zvec is the pure embedded-vector answer (billions of vectors, no graph); NornicDB adds vectors to a Neo4j-compatible graph but stays server-shaped.

The Log — Unifying Abstraction for Real-Time Data is the theory LatticeDB internalizes: durable streams and the graph changefeed make the database itself the event log, with committed writes and their events atomic in one WAL. It's the same tables/events duality Kreps describes, minus the distributed transport.

On the query language, LatticeDB's Cypher subset and [Icebug Format](/browse/Icebug%20Format)'s Cypher schema both treat Cypher as the graph lingua franca, but LatticeDB extends it with <=> and @@ operators rather than staying pure-Cypher.

#tool #project #database #graph #vector #search #memory #agents


Sources: raw/latticedb, LatticeDB Last updated: 2026-09-04