Loveliness

A clustered graph database built on LadybugDB — like Elasticsearch is to Lucene, Loveliness is to LadybugDB.
A "loveliness" is the collective noun for a group of ladybugs.
LadybugDB is a Kuzu fork — a fast, embedded, columnar graph engine with Cypher support. Loveliness wraps it in a distributed layer: hash-based sharding, Raft consensus, Bloom filter routing, edge-cut replication, and Neo4j Bolt protocol compatibility. Single Go binary, no external dependencies.
Architecture
graph TB
HTTP[HTTP :8080] --> Router
Bolt[Bolt :7687] --> Router
Router[Query Router<br/>Bloom filter → route/scatter]
Router --> S0[Shard 0]
Router --> S1[Shard 1]
Router --> SN[Shard N]
Router -- remote --> TCP[TCP+MsgPack<br/>to peer nodes]
S0 --- WAL[WAL + Backup + Ingest Queue]
Performance
Local (15.7M nodes, 10M edges, 4 shards — Apple M1 Pro)
| Query Type | P50 | QPS |
|---|
| Point lookup | 425us | 10,758 |
| 1-hop traversal | 673us | 1,106 |
| Single write | 365us | 2,526 |
| Aggregation | 57ms | 16 |
| 2-hop traversal | 162ms | 5 |
| Bulk load | 70–190K nodes/sec | — |
Cluster (50M nodes, 50M edges, 12 shards — 4-node Fly.io)
Tested on 4× performance-4x machines (8 vCPU, 16GB RAM each), sjc region. 200 iterations, 16 concurrent workers. Benchmark binary runs inside the cluster on localhost for true in-network latencies.
| Query Type | P50 | P95 | QPS |
|---|
| Point lookup | 2.2ms | 3.2ms | 427 |
| Point lookup (16 workers) | 5.2ms | 12.2ms | 2,642 |
| Range filter | 3.2ms | 3.7ms | 290 |
| Count all nodes | 8.4ms | 11.0ms | 112 |
| Count filtered | 284ms | 310ms | 3 |
| Aggregation (avg) | 295ms | 321ms | 3 |
| Group-by aggregation | 769ms | 814ms | 1 |
| 1-hop traversal | 2.9ms | 380ms | 17 |
| 2-hop traversal | 241ms | 268ms | 4 |
| Variable-length path (1..3) | 2.3ms | 3.3ms | 414 |
| Friend-of-friend count | 476ms | 494ms | 2 |
| Mutual friends | 2.4ms | 3.0ms | 394 |
| Shortest path (1..6) | 29ms | 40ms | 33 |
| Single write | 1.8ms | 2.2ms | 542 |
| Merge upsert | 2.4ms | 3.0ms | 413 |
| Read-after-write | 3.3ms | 4.0ms | 305 |
| Bulk node load | 197K/sec | — | — |
| Bulk edge load | 373K/sec | — | — |
Scale progression
| Dataset | Nodes | Shards | Point lookup P50 | Concurrent QPS | Group-by P50 | Write P50 |
|---|
| 10M / 10M | 3 | 3 | 1.4ms | 1,792 | — | — |
| 20M / 20M | 3 | 3 | 863us | 1,991 | 838ms | — |
| 23M / 23M | 3 | 6 | 1.2ms | 6,831 | 246ms | 1.8ms |
| 50M / 50M | 4 | 12 | 2.2ms | 2,642 | 769ms | 1.8ms |
Point lookups stay sub-3ms through 50M nodes. Writes hold steady at 1.8ms regardless of dataset size. Bulk loading in-cluster hits 197K nodes/sec and 373K edges/sec.
Reproduce Benchmarks
# Full comparison: Loveliness (1-node, 3-node) vs Neo4j CE
./bench/run.sh
# Quick check: single-node Loveliness only
./bench/run.sh --quick
# Custom dataset size
./bench/run.sh --nodes=500000 --edges=500000
# 50M-scale on Fly.io (4 nodes, 12 shards)
./bench/run-50m.sh
Results land in bench/results/<timestamp>/ with JSON data, SVG charts, and a markdown comparison report. CI runs the full comparison on each release and opens a PR with updated results.
Full benchmarks and comparisons with Neo4j, Memgraph, TigerGraph, Neptune, and JanusGraph: docs/benchmarks.md
Neo4j Driver Compatibility
Speaks Bolt v4.x on :7687. Use any Neo4j driver — just change the URL. Both bolt:// (direct) and neo4j:// (routing with automatic failover) are supported.
from neo4j import GraphDatabase
# Direct connection
driver = GraphDatabase.driver("bolt://localhost:7687")
# Routing + automatic failover (recommended for clusters)
driver = GraphDatabase.driver("neo4j://localhost:7687")
with driver.session() as session:
result = session.run("MATCH (p:Person {name: $name}) RETURN p.name, p.age", name="Alice")
72/72 exhaustive tests pass with the official Python driver. Details: docs/bolt.md
Quick Start
Fastest way — one command, real 3-node Raft cluster on your laptop:
loveliness up 3
That's it. Three nodes, auto-configured ports, auto-bootstrap. Connect at bolt://localhost:7687 or http://localhost:8080.
From source: