The first database where time
is a first-class citizen.
MemDB is a bi-temporal graph + vector database built from the storage layer up. Every record (every node, every edge, every embedding) knows when it was true. That single architectural decision makes possible a class of queries no other database can answer: replayable, point-in-time, semantic-and-structural retrieval over evolving codebases. In one round-trip. With no index rebuild.
Three properties. No existing database combines them.
Datomic has bi-temporal but no vectors. Pinecone has vectors but treats time as metadata. Neo4j is graph-native but has no vectors. MemDB combines all three at the record-header level. Not a feature flag, a foundational choice.
Native graph traversal
Every node and edge is a first-class record. Type-aware traversal: CALLS, DEPENDS_ON, IMPLEMENTS, natively, not via a join table.
Native HNSW vectors
Embeddings stored as records, not auxiliary indices. Each vector carries its own bi-temporal header so similarity queries can be replayed at any past timestamp.
Bi-temporal record headers
Every record carries valid_at (when this fact became true) and invalid_at (when it stopped). Append-only: nothing is ever overwritten.
A single as_of_time predicate
Flows uniformly through ANN similarity, graph traversal, and metadata filtering. One query, one round-trip, any point in time.
Every record carries the same 32-byte header.
Vector records, graph nodes, edges, metadata: all share one structure. The visibility rule is uniform: a record is visible at query time T if and only if valid_at ≤ T < invalid_at.
The header
32 bytes in front of every record: vector, node, edge, or property. This is the only place in the database where time lives. Applications above it never see it.
struct RecordHeader { rid: u64, // record identifier valid_at: i64, // when this fact became true invalid_at: i64, // when it stopped, i64::MAX = still valid transaction_at: i64, // when this record was written episode_id: u64, // grouping for atomic multi-record changes schema_ver: u16, kind: u8, flags: u8, }
One predicate. Four phases. Zero round-trips.
The as_of_time argument flows through every phase of the query. Vectors, graph hops, metadata filters: all see the same point-in-time view, computed once, returned in milliseconds.
FusionQuery::ann().as_of(T).then_walk(…)
Filter HNSW candidates
Vectors invalid at T excluded before distance computation, so no wasted similarity work.
Walk the graph
Multi-hop from seed candidates. Each node and edge filtered by the same valid_at ≤ T < invalid_at.
Apply metadata filters
Property predicates use the value of the property valid at T, not the current value.
Rerank & return
Final score combines similarity, graph distance, and any application signal. Ranked, replayable, deterministic.
Reproducible from the repo. Every one.
Measured on Apple Silicon, runnable via cargo bench. Result JSONs with commit SHA, hardware, kernel, and HDR histogram raw data.
Process spawn → first answerable query. Spec target was 500ms. 71× under target.
p50 across 48,566 iterations. Spec target was 3ms. 3.3× under target.
Peak RSS. Spec target was 75 MB. 22% of budget. Fits on a laptop alongside the agent.
Plus 12.1× faster graph traversal, 5.7× faster ANN. Time-travel: infinite. They can't.
Everyone has two of three. No one has all three.
The patent surface is the unified as_of_time predicate threaded through ANN + graph + metadata. Provisional patent filing in flight.
Memtrace’s code map runs on it. The Fleet writes to it.
MemDB is the memory inside Memtrace
that makes the whole thing possible.
Audit logging. Time-travel debugging. Regulatory compliance for ML. MemDB, the memory with time built in inside Memtrace, is the primitive everything else is built on. That’s the moat.