Skip to main content

In-memory · Cypher · Rust

Everything LoraDB supports — and what it doesn’t.

A complete map of the engine — Cypher coverage, surfaces, architecture, and the lines we won’t pretend to cross. Pick what you came here to verify.

  • One Rust engine · seven surfaces
  • Full Cypher pipeline — parse, analyze, compile, execute
  • Local-first · embeddable · open source

Design principles

The bets the engine took.

01

Relationships are first-class

Edges are typed, directed, and property-bearing. Traversal is O(degree), not a stack of self-joins.

02

Cypher where it counts

A pragmatic subset of Cypher — MATCH, WITH, WHERE, CREATE, RETURN. Short queries, readable intent.

03

Schema-free by design

Add a label, an edge type, or a property by writing it. No ALTER, no migration, no restart.

04

Small enough to read

A compiler-style pipeline of focused crates from parser to executor. If the database matters to your product, you should be able to read it.

Cypher coverage

The Cypher you actually write — supported.

Pattern matching, writes, aggregation pipelines, paths, temporal and spatial predicates — composed top-to-bottom with WITH.

Pattern matching

MATCH (a:Person)-[:KNOWS]->(b:Person)
WHERE a.city = 'Berlin'
RETURN a.name, collect(b.name) AS friends
MATCH reference

Writing data

MERGE (u:User {email: $email})
ON CREATE SET u.created = datetime()
ON MATCH  SET u.last_seen = datetime()
MERGE reference

Variable-length paths

MATCH p = shortestPath(
  (a:Stop {code: $from})-[:CONNECTS*..6]->(b:Stop {code: $to})
)
RETURN length(p) AS hops, [n IN nodes(p) | n.code] AS via
Paths reference

Aggregation pipelines

MATCH (u:User)-[:PLACED]->(o:Order {status: 'paid'})
WITH u, count(o) AS orders, sum(o.total) AS spend
WHERE orders >= 3
RETURN u.email, orders, spend ORDER BY spend DESC
Aggregation reference

Temporal predicates

MATCH (e:Event)
WHERE e.at >= datetime() - duration('P7D')
RETURN date(e.at) AS day, count(*) AS events
ORDER BY day
Temporal types

Spatial distance

WITH point({latitude: 52.52, longitude: 13.405}) AS origin
MATCH (s:Store)
WHERE distance(s.loc, origin) < 5000
RETURN s.name, distance(s.loc, origin) AS metres
ORDER BY metres
Spatial types

Functions & types

60+ built-ins. Every value typed.

Architecture

A compiler-style pipeline you can read.

Every query walks a real pipeline — parser, analyzer, compiler, executor — written from scratch in Rust. Each stage is one crate; the names line up with the source tree.

  1. 01

    Parse

    lora-parser

    A PEG grammar lifts Cypher text into a typed AST with source spans.

  2. 02

    Analyze

    lora-analyzer

    Variable scoping, label and type validation against live graph state, function resolution.

  3. 03

    Compile

    lora-compiler

    Lower the resolved IR into a logical plan, optimize (filter push-down), then a physical plan.

  4. 04

    Execute

    lora-executor

    Interpret the physical plan against the in-memory store and project results in the requested shape.

Open the sourceRead the engine on GitHub

Ways to use it

One engine, seven places to reach it.

Pick the surface that fits the host process. Cypher, parameters, and result shapes are identical across all of them.

lora-databasemain.rs
use lora_database::Database;

let db = Database::in_memory();
db.execute("CREATE (:User {name: 'Ada'})", None)?;

let result = db.execute(
    "MATCH (u:User) RETURN u.name",
    None,
)?;
Rust guide

Know the boundary

What LoraDB does not pretend to be.

LoraDB is an in-memory engine, not a clustered production database. Below is what to expect — stated up front so you can decide whether the trade-offs match your workload.

In-memory engine

The graph lives in process memory. Durability is optional via snapshots and WAL, not a separate persistent storage backend.

No property indexes

Predicates are evaluated by scan. Plenty fast for the workloads above; not a substitute for an indexed planner.

Single global lock

The executor holds one mutex per database. Great for embedded and per-request use; not for high-fan-out concurrency.

No auth or TLS in core

lora-server is meant to live behind your own ingress. The crate has no auth surface — you control the host process.

Open a database. Run a query.

Three lines of Rust, a curl call, or a single import. The fastest way to feel LoraDB is to write a query against it.