HydraDB
HydraDB is an object-store-native distributed graph database written in Rust. It combines durable graph storage on SlateDB with snapshot-consistent OpenCypher queries, GraphBLAS traversal, Neo4j-compatible Bolt connectivity, and an HTTPS query API.
Storage and compute are fully disaggregated. S3-compatible object storage is the
durable source of truth, and compute runs as two independent roles: data
nodes (graph-node) serve queries and canonical mutations, while indexers
(graph-indexer) build immutable traversal indexes in the background. Both keep
only disposable state in memory and on local SSD or NVMe, so they can be replaced
or scaled without moving the graph itself.
Why HydraDB
- Object-store durability. Graph records, WALs, manifests, and immutable traversal indexes live in S3-compatible storage.
- Independent compute. Data nodes and indexers scale separately and can rebuild their local caches from durable state.
- Safe writer handoff. Object-store CAS leases select the active writer for each cell, while SlateDB writer epochs fence stale writers.
- Consistent reads. Every query runs against one pinned SlateDB snapshot. Indexed traversal combines a compiled CSC generation with its visible WAL overlay.
- Graph-native execution. The planner uses property indexes, reverse adjacency, sparse traversal, and SuiteSparse GraphBLAS where appropriate.
- Familiar clients. Applications can use Neo4j drivers over Bolt 5.x or the typed JSON and streaming NDJSON HTTP API.
- Bounded operation. Authentication, authorization, deadlines, result limits, backpressure, cancellation, cache budgets, metrics, and traces are part of the server runtime.
Architecture
flowchart TB
C["Applications<br/>Neo4j drivers or HTTPS"]
SVC["Service or load balancer"]
subgraph Q["Data tier — graph-node"]
direction LR
subgraph N1["graph-node"]
Q1["query + mutation engine"]
S1["local SSD / NVMe cache"]
Q1 <--> S1
end
subgraph N2["graph-node"]
Q2["query + mutation engine"]
S2["local SSD / NVMe cache"]
Q2 <--> S2
end
end
subgraph I["Indexing tier — graph-indexer"]
IX1["graph-indexer"]
IXN["graph-indexer"]
end
STORE["S3-compatible object storage<br/>WAL, SSTs, leases, CSC generations"]
C --> SVC
SVC --> N1
SVC --> N2
N1 <--> STORE
N2 <--> STORE
IX1 <--> STORE
IXN <--> STORE
Each data node owns a private local SSD/NVMe cache; the object store is the shared layer beneath the whole tier and the only durable copy of the graph.
Data nodes serve reads and canonical graph mutations. Indexer workers build immutable CSC generations asynchronously and publish them through atomic object-store pointers. Readers remain correct when an index is absent or behind because the visible WAL tail is applied to the indexed base.
See architecture.md for the storage model, query pipeline, writer coordination, index lifecycle, and failure semantics.
Getting Started
There are two ways to bring up a single development node: the published Docker image, or a build from source. Either way, once the node is listening, use [Verify a running node](#verify