Orchestrata Ultimate › Plans › research-oss-graph-alternatives-2026-07-06

Open-source Neo4j alternatives — research (2026-07-06)

Source: plans/research-oss-graph-alternatives-2026-07-06.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-06 · 225 lines.

Prose pending.

Plan text

Open-source Neo4j alternatives — research (2026-07-06)

Question (user): what genuinely open-source alternatives to Neo4j exist, and should Orchestrata adopt one? "Open source" = OSI-approved license only; source-available (BSL/SSPL/Elastic/FSL) is disqualifying.

Adopter profile: Python 3.14, official neo4j driver over Bolt, self-hosted incus containers, no cloud. Cypher: MERGE-heavy small transactions from parallel writers, Neo4j-5 constraint DDL (FOR ... REQUIRE ... IS UNIQUE), datetime() temporals with ORDER BY, label+property indexes, some full-text. The graph is the system of record (~250K nodes, growing). Needs one durable production instance + a fleet of 3–6 disposable test instances where RAM-per-instance and startup seconds matter (worker-parallel test suite, <5-min wall-clock goal).

Evaluation bar (sharpened by the TestRun incident and Memgraph findings):

  1. License: OSI-approved, verified against the LICENSE file, governance noted.
  2. Drop-in-ness: does the official neo4j Bolt driver work? Constraint DDL dialect?
  3. Semantics, not just syntax: MERGE behavior under concurrent writers (lock-based vs optimistic+retry), ORDER BY null placement (nulls-first-on-DESC just caused a real bug here), temporal type fidelity.
  4. Durability: per-commit fsync? WAL+snapshot model? (Memgraph's default fsync every 100K tx is the cautionary example.)
  5. Fleet economics: idle RSS, cold-start seconds, container story.
  6. What it buys over Neo4j CE's GPLv3 gates: CE has NO replication, offline-only backup, no multi-database, no RBAC.

Survey — genuinely open-source candidates

Two structural findings (landscape agent, all licenses verified against LICENSE files, July 2026):

  1. There is NO genuinely open-source, production-grade, Bolt-compatible Neo4j alternative. Bolt speakers: Neo4j itself (GPLv3), Memgraph (BSL — disqualified), TuGraph-DB (partial Bolt, Apache-2.0, thin community/cadence), ONgDB (AGPLv3 fork frozen at Neo4j-4.3-era parity, dormant). "Keep the driver, swap the server" is not on the table.
  2. The licensing landscape churned hard 2024–2026: ArangoDB → BUSL (3.12); Kùzu abandoned Oct 2025 (sponsor acqui-hired), revived as MIT LadybugDB; Dgraph fully Apache-2.0 in v25; HugeGraph became an ASF top-level project (2026-02); FalkorDB turns out to be SSPL (not OSS, despite marketing); RedisGraph EOL'd 2025-01. Re-verify licenses at adoption time, always.
Engine License (verified) Query lang Bolt? Fleet economics Verdict
Neo4j CE 5.26 LTS GPL-3.0 Cypher (reference) native ~512MB–1GB JVM, 10–30s start Incumbent; ALL our features are in CE; LTS to 2028-06
Apache AGE Apache-2.0 (ASF) openCypher subset in SQL no (PG wire) ~50–100MB, <1s — best server fleet story Best license/governance; port not a swap: no temporals in Cypher layer, no constraints, agtype parsing
LadybugDB (Kùzu fork) MIT Cypher dialect, schema-first no (embedded) megabytes, in-process, DB=directory Closest dialect + unbeatable test-fleet mechanics; 9-month-old fork, format stability unproven
ArcadeDB (OrientDB successor) Apache-2.0 native openCypher-25 + SQL/Gremlin no (PG wire, {cypher} prefix) few-hundred-MB JVM, seconds Un-gates what Neo4j gates (multi-DB + HA free); young Cypher engine, small vendor
Dgraph v25 Apache-2.0 DQL/GraphQL — no Cypher no moderate Go Wrong direction: full query rewrite
NebulaGraph Apache-2.0 nGQL (no MERGE, no constraints, no transactions) no 3 daemons, multi-GB OSS core de-facto terminal (last release 2024-05; vendor on proprietary v5)
JanusGraph Apache-2.0 (LF) Gremlin no JVM + Cassandra/Scylla stack Heavy + rewrite; poor fit
Apache HugeGraph Apache-2.0 (ASF TLP 2026-02) Gremlin-first, 2nd-class openCypher no ~1GB JVM Healthy project, weak fit; RCE history (CVE-2024-27348)
TypeDB MPL-2.0 TypeQL (paradigm shift) no Rust, moderate Out of scope for Cypher-first
OrientDB Apache-2.0 SQL/Gremlin no JVM Maintenance mode; take ArcadeDB instead
TuGraph-DB Apache-2.0 openCypher + ISO GQL partial moderate C++ Only Apache+Bolt engine; China-centric, cadence cooling (last release 2025-03)
AgensGraph Apache-2.0 + PG Cypher-in-SQL (PG fork) no PG-like AGE is the same idea, better architecture/governance

Disqualified (source-available, verified): Memgraph (BSL 1.1 — Appendix A), FalkorDB (SSPLv1 per its own license page; GitHub shows NOASSERTION), ArangoDB ≥3.12 (BUSL-1.1 + 100GiB non-commercial community binary), SurrealDB (BSL 1.1), RedisGraph (EOL 2025-01; successor is FalkorDB, SSPL).

ISO GQL (39075:2024) convergence: Cypher-derived; Neo4j Cypher 25 (2025.06+) aligns grammar with GQL and openCypher has redefined itself as "paving the road to GQL" — so Cypher-shaped code is the portability hedge, and staying on Neo4j CE does not strand us. TuGraph ships actual GQL; SQL/PGQ (DuckPGQ, MIT) is the relational adjacent.

Deep-dive — Apache AGE / Kùzu(LadybugDB) / FalkorDB / NebulaGraph

Five-agent web research, kill-critical claims verified against primary sources (license files, GitHub APIs, official docs). Full agent report in the session transcript; the decisive facts:

Apache AGE (Apache-2.0, ASF TLP — the right license and governance):

Kùzu → LadybugDB (MIT): Kùzu Inc. archived everything 2025-10-10 — the team was acqui-hired by APPLE (EU filing surfaced 2026-02). LadybugDB is the leading fork (~monthly releases). One RW process per database (file lock), single effective writer within it — the Vela fork exists specifically to add multi-writer. ORDER BY defaults NULLS FIRST ascending (opposite of Neo4j). No datetime(), no CALL {}, PK-only uniqueness, DDL-first schema. Frozen corruption-bug ledger from 0.11.3. Our first-party spike (above) measured the rest. Graphiti deprecated its Kuzu backend; GitLab is migrating off.

FalkorDB: SSPLv1 per its own README/LICENSE — source-available, disqualified. Its Bolt support is marked "experimental, not for production" by its own docs. Re-evaluate only if it relicenses.

NebulaGraph OSS (Apache-2.0, single vendor + CLA): last OSS release v3.8.0 2024-05-17 — 26 months, 3 master commits in 18 months, nightlies stopped; vendor ships proprietary v5.x. nGQL: NO MERGE (official FAQ), no constraints (VID-only identity), NO transactions, no CALL; docs verbatim: "Don't use UPSERT for scenarios with highly concurrent writes" — our exact workload. 3-daemon topology, 8GB test minimum, ~20s async DDL. Out on every axis.

Neo4j CE baseline precision (verified): GPLv3; exactly ONE user database; property-UNIQUENESS constraints only (existence/type/key = Enterprise); no RBAC (all users implied admins); offline dump only; 5.26 LTS supported to 2028-06-06 (next LTS ~2026-11). Everything Orchestrata uses today is in CE. The only OSI-licensed Bolt speaker in 2026 is ArcadeDB (Apache-2.0, Bolt 3.0/4.0/4.4 plugin, vendor-claimed 97.8% openCypher TCK) — the escape hatch.

First-party LadybugDB spike (2026-07-06, v0.18.0, user-directed)

Isolated venv, our workload shape. Full script: scratchpad ladybug-spike/spike.py.

Mechanics (excellent): fresh DB + schema in 0.05s; reopen 0.87s; PK uniqueness enforced (RuntimeError on dup); traversal fine; ORDER BY DESC places nulls FIRST — same semantics as Neo4j Cypher.

Disqualifiers for OUR test fleet (measured, not assumed):

  1. Single-writer per database, even in-process: 3 of 4 concurrent MERGE threads → "Cannot start a new write transaction. Only one write transaction". Tests that exercise real parallel writers cannot run, let alone pass.
  2. Schema-first: CREATE (x:BrandNewLabel) → Binder exception (every label needs a pre-declared NODE TABLE). Our test_id-tagged ad-hoc nodes = rewrite all.
  3. Verbatim Neo4j-Cypher probes: 5/5 fail — Neo4j-5 constraint DDL (parser), datetime() (no such function; TIMESTAMP params work), schemaless labels, CALL {} subqueries, shortestPath().
  4. No cp314/cp314t wheel; sdist fails to build on 3.14 — the suite's free-threaded interpreter cannot import it at all (spike ran on 3.13).
  5. Footprint reality: 443MB RSS after ~15K nodes (default buffer pool), not the promised megabytes; MERGE throughput ~910/s single-threaded — no write win.

Verdict: a LadybugDB test fleet would be maximal split-brain — tests would no longer exercise the production engine's dialect, schema model, OR concurrency semantics. The Neo4j-clone fleet ruling stands, now empirically. Legitimate future niche: greenfield embedded graph scratch-space (per-run analysis caches), not the system-of-record path and not this suite.

Recommendation

Stay on Neo4j 5.26 Community — deliberately, with two hedges.

Every candidate fails a load-bearing requirement of THIS workload:

Meanwhile Orchestrata's whole feature surface (Bolt + official driver, unique constraints, lock-based concurrent MERGE, datetime() with defined null order, full-text) sits inside CE's GPLv3 set, LTS to 2028-06. CE's gates all have operational answers here: one-DB-per-instance is already the fleet model; offline-dump backup is covered by incus/Btrfs snapshots + periodic dumps; RBAC/clustering unneeded at this scale.

Hedges: (1) ArcadeDB is the designated escape hatch (only Apache-2.0 Bolt engine) — spike it only if a Neo4j Enterprise gate ever actually blocks us. (2) Keep Cypher GQL-convergent and constraints declared in ONE place (done: canonical_schema.py, c295195b) so any future exit is cheap. Re-evaluate at the next Neo4j LTS (2026-11), if AGE ships released ON-CREATE-SET + constraint DDL, or if FalkorDB relicenses.


Appendix A — Memgraph (disqualified: source-available), 4-report synthesis

Researched in depth before the OSS-only scope was set; retained because it calibrates the bar. Version 3.11.0 (2026-06-17), ~6-week release cadence.

License (the disqualifier) — BSL 1.1 as amended 2026-01-01; the text self-declares "not an 'open source' license". Internal production use: free, unlimited. Forbidden: embedding/distribution to third parties, DBaaS, "competing" products. The Jan 2026 amendment quietly DELETED the previous grant's integrated-solution + SaaS clauses (ISV/embedders must now buy an OEM license; changed via GitHub PR, no announcement). Per-version reversion to Apache-2.0 after 4 years (all 2.x already reverted — open source but unsupported). MAGE went Apache-2.0 → BSL in the 2025-11 monorepo merge; mgconsole is GPLv3; Lab is closed freeware ("not licensed for production use" clause). Dynamic algorithms moved into Enterprise at 3.0 (2025-01). Multi-tenancy: Enterprise. Auto-failover: Enterprise (SYNC/ASYNC replication itself is free — more generous than Neo4j CE, which has none).

Technical drop-in verdict — fails even ignoring license:

Durability caution: default WAL fsync every 100,000 transactions (--storage-wal-file-flush-every-n-tx) — committed-transaction loss window on crash unless set to 1. Snapshots mandatory (WAL-only not possible); snapshot/WAL formats NOT compatible across versions (dump/load upgrades).

Fleet economics (the part worth envying): ~75 MB idle RSS; ~205–550 MB for our graph size; IN_MEMORY_ANALYTICAL mode (no WAL/deltas/snapshots) is purpose-built for disposable test instances; 220 MB image, non-root (uid 101), healthcheck via mgconsole; tmpfs-friendly.

Vendor risk: ~25–30 staff; $14.2M total funding, none since 2023-12, no Series A; hard pivot to GraphRAG/agentic-AI; single-vendor development (no community commits to speak of); 4.2K stars / 2.7K Discord.

Appendix B — AWS Neptune (disqualified: proprietary managed service)

Not open source in any form, no self-hosting, openCypher dialect without schema constraints, and cloud cost per instance-hour is structurally wrong for a run-dozens- of-times-daily local test fleet. Ruled out on scope; not researched further.