jeffhajewski/latticedb
Embedded single-file knowledge graph database with vector search and full-text search for AI/RAG apps
LatticeDB – an embedded graph‑plus‑vector‑search database
What it is – LatticeDB is a single‑file, embedded property‑graph database that also indexes high‑dimensional vectors (via HNSW) and full‑text (BM25). It lets a local program query the same data by relationships, semantic similarity, or keyword search using one Cypher‑style query language.
Key selling points
- One file, zero config – the whole database (graph, vectors, FTS, WAL) lives in a portable file; no server process is required.
- Unified query layer –
MATCH … WHERE node.embedding <=> $vec < 0.3 AND node.text @@ "keyword"works in a single statement. - Embedded, single‑writer model – ideal for desktop apps, tools, or agents that run on a single machine.
- Fast – sub‑microsecond node look‑ups, ~0.8 ms 10‑NN search on 1 M vectors with 100 % recall, and 19 µs BM25 text search.
- Bindings – native C API plus first‑class libraries for Python, TypeScript/Node, Go, and Java.
Installation
| Language | Command |
|---|---|
| CLI | curl -fsSL https://raw.githubusercontent.com/jeffhajewski/latticedb/main/dist/install.sh | bash |
| Python | pip install latticedb |
| TypeScript / Node | npm install @hajewski/latticedb |
| Java | Build the JNI bridge (JDK 21+) via the bindings/java README. |
| Go | Follow bindings/go/README.md (cgo workflow). |
The packages bundle the native liblattice library on supported platforms; you can also stage a custom build with the LATTICE_BUNDLE_LIB_DIR env var.
Quick example (Python)
from latticedb import Database
from latticedb.embedding import hash_embed
with Database("knowledge.db", create=True, enable_vectors=True, vector_dimensions=128) as db:
db.create_node_fts_index("Chunk", "text")
with db.write() as txn:
alice = txn.create_node(labels=["Person"], properties={"name": "Alice"})
doc = txn.create_node(labels=["Document"], properties={"title": "Attention Is All You Need"})
chunk = txn.create_node(labels=["Chunk"], properties={"text": "The transformer architecture uses self‑attention..."})
txn.set_vector(chunk.id, "embedding", hash_embed("transformer self‑attention", 128))
txn.create_edge(chunk.id, doc.id, "PART_OF")
txn.create_edge(doc.id, alice.id, "AUTHORED_BY")
txn.commit()
results = db.query(
"""
MATCH (c:Chunk)-[:PART_OF]->(d:Document)-[:AUTHORED_BY]->(a:Person)
WHERE c.embedding <=> $q < 0.5
RETURN d.title, c.text, a.name
ORDER BY c.embedding <=> $q
LIMIT 5
""",
parameters={"q": hash_embed("attention mechanism", 128)}
)
for r in results:
print(r["d.title"], "by", r["a.name"])
The same pattern works in TypeScript, Go, and Java (see the README for full snippets).
Performance highlights (from the repo’s benchmarks)
| Operation | Latency | Throughput |
|---|---|---|
| Node lookup (cached) | 0.13 µs | 7.9 M ops/s |
| 10‑NN HNSW (1 M vectors) | 0.83 ms (mean, 100 % recall) | 1.2 K queries/s |
| Full‑text BM25 (100 docs) | 19 µs | 53 K queries/s |
| 2‑hop graph traversal (100 K nodes) | 39 µs | – |
Compared to popular alternatives, LatticeDB’s node look‑ups match in‑memory RocksDB, its vector search beats FAISS single‑threaded HNSW and is on par with server‑based Weaviate/Qdrant, while its BM25 search is ~300× faster than SQLite FTS5.
Core features
- Graph – labeled nodes/edges, property indexes, ACID transactions, MERGE/UNWIND, aggregations.
- Vector search – HNSW ANN, configurable
M/ef, bulk ingestion, built‑in hash embed helper or HTTP client for real models. - Full‑text – BM25 inverted index, tokenization, stemming, fuzzy Levenshtein search.
- Cypher dialect –
MATCH,WHERE,RETURN,CREATE,DELETE,ORDER BY,LIMIT, plus custom operators<=>(vector distance) and@@(text match). - Durability – write‑ahead log, point‑in‑time backup, hot backup, compacting freelist.
- Event streams – named changefeeds share the same WAL, useful for reactive agents.
- In‑memory mode –
:memory:opens a transient DB with no file I/O.
Typical use cases
- Local knowledge bases, note‑taking apps, or personal search tools that need both graph relationships and semantic search.
- Agent memory / RAG pipelines where a single process stores chunks, embeddings, and metadata and queries them together.
- Prototyping graph‑centric applications without running a separate server (lightweight alternative to Neo4j or Weaviate).
When to look elsewhere
- Multi‑process or networked workloads – LatticeDB only allows one writer at a time.
- Purely tabular data – a relational DB (SQLite, PostgreSQL) may be simpler.
- Massive concurrent writes or distributed scaling – a client‑server system (e.g., Neo4j, Qdrant) is more appropriate.
Where to go next
- Getting started –
docs/getting_started.mdwalks through CLI, Python, TS, Go, and Java setups. - Examples – see
examples/cli,examples/go, and the language‑specific READMEs for runnable demos. - Benchmarks – run
zig build benchmarkor the specific vector/graph/FTS benchmarks to reproduce the numbers.
LatticeDB is a purpose‑built engine for anyone who wants a fast, local, single‑file store that can handle graph traversals, vector similarity, and full‑text search all together.
Related
- Dispatch
- Project
- Project
- Project
- Project