Skip to main content

Engineering journal

LoraDB Blog

Engineering notes, architecture pieces, release notes, and design writing from the LoraDB team.

LoraDB v0.4.0: WAL, checkpoints, and crash recovery

· 6 min read
The LoraDB team
Engineering

LoraDB v0.4.0 adds a write-ahead log.

The engine is still in-memory and local-first. What changes in this release is the durability boundary: on the surfaces that own a filesystem and process lifecycle, committed writes no longer have to live entirely in RAM between two manual snapshots.

The shortest mental model:

  • createDatabase() in Node is still a fresh in-memory graph.
  • createDatabase("application", { databaseDir: "./data" }) opens a persistent archive-backed graph at ./data/application.loradb.
  • Database.create("app", {"database_dir": "./data"}), lora.New("app", lora.Options{DatabaseDir: "./data"}), and LoraRuby::Database.create("app", {"database_dir": "./data"}) do the same thing on Python, Go, and Ruby.
  • lora-server --wal-dir /var/lib/lora/wal turns the HTTP server into a WAL-backed process.
  • Rust gets the full open, recover, checkpoint, and sync-mode surface.

Snapshots do not go away. They stay the portable file you can back up, ship, and restore elsewhere. v0.4.0 makes them stronger by giving them something to checkpoint against.

Snapshots before a log

· 8 min read
Joost van Berkel
Author, LoraDB

Most databases I have worked with had a write-ahead log before they had a snapshot story. LoraDB went the other way.

v0.3 ships manual point-in-time snapshots and nothing else on the persistence side. No append-only log. No background checkpoint loop. No continuous durability. One file on disk, taken on demand, atomic on rename.

The order is intentional, and it is the kind of decision that is easier to defend before the release than after.

LoraDB v0.3: snapshots for saving and restoring graph state

· 12 min read
The LoraDB team
Engineering

LoraDB v0.3 adds manual point-in-time snapshots.

You can now dump the entire in-memory graph to a single file and restore it later. The save is atomic on rename, the load replaces the live graph in one shot, and the feature is exposed on every surface that the engine talks through — the Rust core, the Python, Node, WASM, Go, and Ruby bindings, the shared C FFI, and the HTTP server as an opt-in admin endpoint.

What this release is not is full persistence. There is no write-ahead log, no background checkpoint loop, no continuous durability. A snapshot is exactly what the name says: a point-in-time dump you take on demand. Data mutated between two saves is lost on crash. That boundary is deliberate — making the explicit, operator- controlled shape work cleanly is the foundation a WAL will sit on, and it closes the "no persistence at all" gap for the workloads that only need occasional checkpoints today (seeded services, notebooks, controlled shutdowns, scheduled backups).

LoraDB v0.2: vector values for connected AI context

· 10 min read
The LoraDB team
Engineering

LoraDB v0.2 adds first-class VECTOR values.

You can now construct vectors in Cypher, store them as node or relationship properties, pass them in as parameters through every binding, and run exhaustive similarity search against them. The value type, the wire format, the function surface, and the binding helpers all landed together so vectors behave like every other typed value in the engine.

What this release is not is a vector-index product. There is no approximate nearest-neighbour search, no built-in embedding generation, and no plugin compatibility layer. Those are deliberately out of scope for v0.2. The goal here is to make embeddings comfortable inside the graph model — to ship the foundation that an index-backed retrieval path will eventually sit on.

Vectors belong next to relationships

· 9 min read
Joost van Berkel
Author, LoraDB

The conventional advice for AI retrieval is to pick a side.

You pick a vector database if you want similarity. You pick a graph database if you want structure. You bolt them together with glue code when the product inevitably needs both.

That framing has never matched the workloads I actually care about. The interesting systems — agent memory, recommendations, internal search over connected product data, knowledge graphs that feed chat features — do not want a vector store or a graph store. They want to retrieve candidates by similarity, then explain and filter those candidates by relationships. Splitting that into two products splits the query path, the data model, and eventually the team.

LoraDB v0.2 adds VECTOR as a first-class value type. Vectors live directly on nodes and relationships, next to labels, properties, and edges. The argument is not that a graph database should replace a vector database. The argument is that similarity belongs next to the relationships that give it meaning.

LoraDB public release: a fast in-memory graph database in Rust

· 7 min read
The LoraDB team
Engineering

LoraDB is now public.

It is a fast in-memory graph database written in Rust, with a Cypher-shaped query engine, an HTTP API, and bindings for Node.js, WebAssembly, and Python. It is built for developers who need relationship queries close to their application without adopting a large graph database stack on day one.

This release is the beginning of the public journey: source-available core, developer-first adoption, and a path toward a hosted platform for teams that want managed operations later.

From developer trust to hosted platform

· 5 min read
Joost van Berkel
Author, LoraDB

The easiest way to misunderstand LoraDB is to see the open core and the hosted platform as separate ideas.

They are the same journey.

The core database has to be developer-first because graph databases ask for a lot of trust. You are not just storing records. You are putting relationships, paths, and product logic into a system that needs to be correct and fast. If a developer cannot run it locally, inspect it, and build confidence in the query engine, the hosted product has no foundation.

Efficient storage is the product

· 6 min read
Joost van Berkel
Author, LoraDB

When people talk about graph databases, they usually talk about query languages, visualizations, and relationship modeling. All of that matters. But for the kind of database I wanted, the deeper product question was storage.

If the database is in memory, storage efficiency is not an implementation detail. It is the product boundary.

Every extra allocation is less graph. Every unnecessary clone is less fan-out. Every vague data structure is a future performance mystery. A graph database can have a beautiful query language and still feel wrong if the storage layer wastes the machine.

In-memory or it does not work

· 5 min read
Joost van Berkel
Author, LoraDB

The phrase "in-memory database" can sound like a performance trick. For LoraDB, it is more basic than that. The product I wanted to build did not make sense if the graph was slow to touch.

Graphs are not like simple key-value lookups. The interesting queries walk. They expand. They branch. They filter while moving through relationships. A single product interaction can turn into a set of small traversals that need to feel instant.

If the graph is on the hot path, latency is not an optimization. It is the product.

Why I started LoraDB

· 5 min read
Joost van Berkel
Author, LoraDB

I did not start LoraDB because the world was missing another database with a logo and a query language. I started it because I kept reaching for a graph database in places where the existing choices felt too heavy for the job.

The shape of the problem was clear: I needed a really fast in-memory graph database. Not a graph feature bolted onto a document store. Not a large server that needed its own operational plan before I could answer a product question. Not a database that looked elegant in a demo but became expensive once the working set, query fan-out, and deployment model got real.

I needed something smaller, sharper, and more efficient.