Why Put a Distributed Graph Database on Object Storage?
HydraDB is a distributed graph database written in Rust, but its defining choice is not the language or the fact that it speaks graph queries. Its durable source of truth is S3-compatible object storage, organized and made transactional through SlateDB, while query-serving nodes and background indexers keep only replaceable working state. The question here is why that separation matters. It gives readers a practical model for judging HydraDB: which part of the system must be preserved, which part may be rebuilt, and what the design must do when those two parts move at different speeds.
A graph database has an awkward combination of needs. Applications want to ask questions about connected things—people who follow one another, entities related through several steps, or routes that satisfy a constraint. Those questions benefit from nearby indexes and memory: traversing a graph by repeatedly fetching remote records can be expensive. At the same time, the graph must survive a process crash, a machine replacement, a rescheduled container, or a change in the number of query workers. If the only useful copy lives inside one process's memory or local disk, replacing that process becomes a data-management event rather than an ordinary operating action.
HydraDB addresses the tension by assigning different responsibilities to different kinds of state. Object storage holds the durable graph and coordination records. SlateDB supplies the storage machinery around those records: write-ahead logs, manifests, sorted-string tables, compaction, snapshots, and writer epochs. A graph-node serves client reads and canonical mutations. A graph-indexer reads durable state and constructs immutable traversal indexes in the background. Local memory, SSD, NVMe, compiled matrices, and result caches are there to reduce repeated work; they are not the authority that decides what the graph contains.
The architectural bet
The most useful way to understand HydraDB is to ask what happens when a compute process vanishes. The answer should be: latency rises while the process warms up, but committed graph data does not vanish with it. A new query node can reconstruct its reader state and caches from the object store. An indexer can rebuild a traversal generation. A local compiled matrix can be discarded and recreated. These are meaningful performance costs, but they are not the same as losing the graph.
That distinction is the architecture's central bet. HydraDB does not treat local state as a small, secretly authoritative database. It treats local state as a performance layer placed above durable records. This permits the query tier and indexing tier to scale or restart independently of the graph itself. It also imposes a discipline: every optimization must be checked against the durable view it accelerates. An index that is fast but behind cannot be allowed to redefine what a query sees. A cache hit cannot make a record visible outside the query's chosen snapshot. A placement hint cannot by itself authorize a write.
The split does not mean that object storage is simply a bucket of independent files. SlateDB stores graph records as database keys in write-ahead logs and sorted-string tables. The logical graph includes vertices, relationships, properties, topology, counts, tombstones, and indexes, but those records participate in storage snapshots and compaction rather than being managed as one object per vertex or edge. The object store is the shared durable layer; SlateDB supplies the database semantics needed to read and change that layer coherently.
The other important consequence is that HydraDB has two different compute roles rather than one enlarged server. A data node handles the request path. It authenticates and authorizes a client, resolves the target graph scope, plans a query, reads a consistent view, or admits a canonical mutation. An indexer has no public query listener and does not open graph writers. Its job is to turn canonical adjacency into immutable traversal materialization that query nodes can discover later. The indexer can be absent or behind without becoming a gate on the basic ability to read or write the graph.
The diagram shows a relationship, not just a deployment topology. Applications reach graph nodes, but graph nodes and indexers meet at the durable object store. The local caches sit beside the query role, and the index generation flows back to readers as a materialized aid. Nothing in that picture makes the indexer the owner of the graph. Its output is useful precisely because the canonical records remain available when the output is missing, old, or being replaced.
Why the separation is consequential
Object-store durability changes what “scaling out” means. In a tightly coupled database, adding or replacing a server can involve moving data, synchronizing local replicas, or preserving a stateful assignment. In HydraDB's intended model, compute processes can be treated more like workers over a shared durable layer. A graph node can retain a private local cache for speed without making that cache part of the storage contract. An indexer can use temporary local space while publishing a durable immutable generation. Kubernetes can therefore replace Pods or scale the two workloads separately, subject to the practical cost of reopening scopes and warming caches.
This is not free elasticity. Object storage is remote, so cold reads, reader refreshes, lease operations, and index construction can pay network round trips. A new process may need to replay durable state before it is warm. An indexer may lag behind active writes, leaving queries to reconcile a published base with recent changes or to use canonical snapshot adjacency. The repository documents the mechanisms that make these choices safe, but it does not by itself establish a universal latency advantage or an availability guarantee for every object-store provider and workload.
The design also chooses bounded behavior over the appearance of unlimited compatibility. HydraDB supports a deliberate subset of OpenCypher, bounded variable-length traversals, typed relationships, native path procedures, Bolt connectivity, and HTTP query surfaces. Unsupported or potentially unbounded forms are rejected rather than being accepted into an execution path whose cost cannot be explained. Query size, runtime, result memory, concurrency, and traversal work have limits. These constraints are part of the architecture's response to remote durable storage: if every request can expand without a bound, a shared object store becomes a difficult place to control failure and tail latency.
The same principle applies to correctness. A compiled traversal index may represent a durable base from an earlier storage sequence. A query that needs a newer sequence can combine that base with a visible tail of committed topology changes when the work is within configured bounds. If the tail is unavailable or too large, HydraDB falls back to canonical snapshot reads. The important choice is not that every query always takes the fastest route. It is that an optimization is allowed to decline when it cannot demonstrate a safe, bounded route to the requested view.
The questions hidden inside the bet
Once durable truth and replaceable compute are separated, several authority questions become unavoidable. Where exactly does one graph live when the deployment serves multiple tenants and cells? Which records are canonical, and which are indexes, counters, tombstones, or coordination hints? How can two query nodes avoid opening competing writers if their local observations differ? How can a reader use an index that was built asynchronously without mixing its topology, metadata, and relationship records across different versions?
HydraDB answers these questions with several mechanisms, but they should not be collapsed into a single idea called “the cluster.” Snapshots define what one query can see. Object-store leases admit a writer for a scope and cell. SlateDB writer epochs fence a stale writer at commit time. Heartbeats and deterministic placement help nodes agree on who should contend. Immutable index generations accelerate traversal but do not replace canonical graph records. Local caches reduce work but do not grant visibility. Each mechanism solves a different problem, and the architecture depends on keeping those problems separate.
That separation is also why failures can be discussed precisely. Losing memory or local SSD should produce a cold path, not data loss. Losing an indexer should produce more overlay or canonical-read work, not a blocked mutation. Losing a lease should retire write authority while allowing a reader to continue where appropriate. A failed view of cluster liveness must not turn uncertainty into an excuse for every node to promote itself. These are not promises that every failure is invisible; they are rules for making the consequence of each failure bounded and intelligible.
The practical judgment supported by HydraDB is therefore narrower and more useful than “object storage is better” or “disaggregation makes databases scalable.” The question is whether a workload values independently replaceable query and indexing compute enough to accept remote durability costs, asynchronous acceleration, a deliberately bounded query surface, and the coordination needed to preserve one writer per cell. That judgment cannot be made from a component list. It depends on knowing which state is allowed to be cold, which state is allowed to lag, and which state must remain authoritative.
The next necessary step is to give that authority model a physical shape. Before following a query or a writer, we need to locate a graph inside HydraDB's namespace, graph, and cell hierarchy and see how canonical records relate to the structures built around them. Only then can “durable truth” mean something more concrete than a reassuring architectural phrase.