ArcadeDB Migration Guide¶
Status: Default graph DB since Phase 2 (2026-05-19; STRATEGY.md DR-11).
TL;DR: ArcadeDB (Apache-2.0, multi-model) replaces Neo4j Community
(GPLv3) as the default graph database. The swap is drop-in for callers
of the neo4j Python driver because ArcadeDB exposes a Bolt-compatible
endpoint. No code in src/ changed; we route through src/db_factory.py
which now defaults ENHANCED_GRAPH_PROVIDER to arcadedb.
1. Why ArcadeDB¶
| Criterion | ArcadeDB | Neo4j Community |
|---|---|---|
| Licence | Apache-2.0 (commercial-distribution safe) | GPLv3 (carve-out required for bundling) |
| Query language | openCypher (drop-in) | Cypher |
| Wire protocol | Bolt (drop-in for neo4j Python driver) |
Bolt |
| Multi-model | Graph + Document + KV + Vector + Time-series + Geospatial | Graph only |
| Operational footprint | Single Java 21+ container; HTTP Studio at port 2480 | Single Java 17+ container; Browser at 7474 |
| Default admin user | root |
neo4j |
Full rationale: STRATEGY.md §4.2
and STRATEGY.md DR-11.
2. What changed in this fork¶
Code¶
- New adapter:
src/db_adapters/graph_arcadedb.py. Thin factory function that callsfrom neo4j import GraphDatabase; GraphDatabase.driver(...)against the ArcadeDB Bolt endpoint -- no new Python dependency. src/db_factory.py:_VALID_GRAPHnow contains{"arcadedb", "neo4j"}, default flipped toarcadedb.get_graph_driver/get_async_graph_driverdispatch through the new adapter when the provider resolves toarcadedb.- All previous call sites already routed through the factory in Phase 1, so no other source files needed changes for this migration.
Infrastructure¶
docker/docker-compose-enhanced-cognee.yml: theneo4jservice is replaced by anarcadedbservice. Container namearcadedb-enhanced-cognee. Bolt is exposed on host port27687(same as the previous Neo4j Bolt port -- drop-in). Studio HTTP at host port22480. ArcadeDB's Bolt plugin is enabled viaJAVA_OPTS=-Darcadedb.server.plugins=Bolt:com.arcadedb.bolt.BoltPlugin.deploy/local/install.ps1anddeploy/local/install.sh: the MCP server registration addsENHANCED_GRAPH_PROVIDER=arcadedb,ARCADEDB_URI=bolt://localhost:27687,ARCADEDB_USER=root, and a strong randomARCADEDB_PASSWORDgenerated at install time (written to the stack.env; no baked-in default). The legacyNEO4J_*env vars are retained pointed at the same host:port for back-compat with any callers still passing them explicitly..env.example:ENHANCED_GRAPH_PROVIDER=arcadedbsection added.
Env vars¶
| Variable | Default | Notes |
|---|---|---|
ENHANCED_GRAPH_PROVIDER |
arcadedb |
neo4j opts into legacy provider |
ARCADEDB_URI |
bolt://localhost:27687 |
host port matches the old Neo4j Bolt port |
ARCADEDB_USER |
root |
ArcadeDB's built-in admin |
ARCADEDB_PASSWORD |
(required, no default) | set in .env; installer generates a strong random value |
NEO4J_URI / _USER / |
(unchanged) | still read when ENHANCED_GRAPH_PROVIDER=neo4j |
_PASSWORD |
||
GRAPH_BACKEND |
unset | legacy alias for ENHANCED_GRAPH_PROVIDER; lower precedence |
3. How to migrate an existing deployment¶
If you already have a stack running Neo4j and want to move to ArcadeDB:
3.1 Export your existing Neo4j data (one-time)¶
The exact command depends on whether you used the _backup_neo4j MCP
tool or neo4j-admin dump. Either output is a Cypher script. The
backup_manager.py Cypher-export fallback writes JSON we can re-import
via restore_backup.
3.2 Switch providers¶
docker compose -f docker/docker-compose-enhanced-cognee.yml down- Pull this branch (or main once Phase 2 is merged).
docker compose -f docker/docker-compose-enhanced-cognee.yml up -d- The new
arcadedbservice comes up; oldneo4j_*volumes remain on disk untouched. - Re-import your data into ArcadeDB through
restore_backupagainst the new endpoint (bolt://localhost:27687-- same URL as before).
3.3 Keep using Neo4j instead¶
Set ENHANCED_GRAPH_PROVIDER=neo4j in your environment and add the
Neo4j compose snippet back to docker-compose-enhanced-cognee.yml
(below). The factory route + integration code stay unchanged; only the
container behind bolt://localhost:27687 differs.
# Neo4j Community fallback (set ENHANCED_GRAPH_PROVIDER=neo4j)
neo4j:
image: neo4j:5.25-community
container_name: neo4j-enhanced-cognee
environment:
NEO4J_AUTH: neo4j/${NEO4J_PASSWORD:-your-db-password}
NEO4J_PLUGINS: '["apoc", "graph-data-science"]'
NEO4J_dbms_security_procedures_unrestricted: apoc.*
NEO4J_dbms_memory_heap_initial_size: 1G
NEO4J_dbms_memory_heap_max_size: 2G
NEO4J_dbms_memory_pagecache_size: 1G
NEO4J_dbms_connector_bolt_listen_address: 0.0.0.0:7687
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
- neo4j_import:/var/lib/neo4j/import
ports:
- "27474:7474" # Browser
- "27687:7687" # Bolt (same host port; comment out the arcadedb mapping above)
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:7474/browser/ || exit 1"]
interval: 30s
timeout: 10s
retries: 3
You cannot bind both services to host port 27687 simultaneously; comment
out the arcadedb port mapping if you want both up at once on
different host ports.
4. Cypher dialect notes¶
ArcadeDB implements openCypher with a few divergences from Neo4j's flavour. The ones that matter for RNR Enhanced Cognee:
| Feature | Neo4j 5 | ArcadeDB | Workaround |
|---|---|---|---|
CREATE CONSTRAINT |
first-class | partial | Use schema commands via HTTP API or ALTER TYPE for indexes |
MATCH (n) DETACH DELETE n |
full | full | -- (this is what recovery_manager._validate_neo4j uses) |
APOC procedures (apoc.*) |
first-class plugin | not available | Replace with native Cypher; APOC is Neo4j-only |
Graph Data Science (gds.*) |
plugin | not available | Out of scope for memory store |
RETURN COUNT(n) |
full | full | -- (used by validate paths) |
elementId(n) |
full | not available | Use id(n) -- ArcadeDB returns numeric/Rid id; backup_manager.py already abstracts via element_id(node) helper |
| Multi-database support | yes (USE db) |
partial (datab. per server) | Use cognee_graph as the single default database |
RNR Enhanced Cognee's existing Cypher usage (in src/agent_memory_integration.py,
backup_manager.py, recovery_manager.py) uses only the rows marked
"full" above. No code changes were required for the migration.
If you hit a query that fails on ArcadeDB, please open an issue and add it to the table.
5. Operational considerations¶
- Memory: ArcadeDB runs on Java 21+. Default JVM heap is ~1 GB
inside the container; tune via
JAVA_OPTS=-Xmx2gif needed. - Studio UI: http://localhost:22480 (login:
root/your-db-password). Equivalent to Neo4j Browser. - Health check: ArcadeDB exposes
GET /api/v1/readyon the HTTP port; the compose health-check uses that endpoint. - Hetzner CX22 (4 GB RAM): stack fits, but if you also run the SigNoz observability stack (Phase 4) on the same host you'll be tight. Consider running observability on a separate VPS.
6. Verification¶
Quick smoke test¶
# Defaults (no env vars set)
python -c "from src.db_factory import get_provider_summary; print(get_provider_summary())"
# {'relational': 'postgres', 'vector': 'qdrant', 'graph': 'arcadedb', 'cache': 'valkey'}
# Get a driver (no live DB needed for this -- import only)
python -c "from src.db_factory import get_graph_driver; print(get_graph_driver.__doc__[:80])"
# Confirm the legacy alias still works
GRAPH_BACKEND=neo4j python -c "from src.db_factory import get_provider_summary; print(get_provider_summary())"
# {'graph': 'neo4j', ...}
Against a running ArcadeDB instance¶
docker compose -f docker/docker-compose-enhanced-cognee.yml up -d arcadedb
# Wait ~10-15s for ArcadeDB to start, then:
curl -s http://localhost:22480/api/v1/ready
# {"status":"OK"}
# Through the MCP server:
python -c "
import asyncio
from bin.enhanced_cognee_mcp_server import init_enhanced_stack
asyncio.run(init_enhanced_stack())
"
# Should log: 'OK ArcadeDB connected' (or 'OK Neo4j connected' label,
# since the existing init code still uses the neo4j label; cosmetic only).
7. Rollback plan¶
If something breaks in production:
- Set
ENHANCED_GRAPH_PROVIDER=neo4jin your.env. - Swap the compose
arcadedbservice back for theneo4jblock in §3.3. docker compose down && up -d.
The neo4j_data, neo4j_logs, neo4j_import volumes are still
declared in the compose file (just unused by default), so your previous
data is still on disk.
8. References¶
- ArcadeDB documentation: https://docs.arcadedb.com/
- ArcadeDB Bolt plugin: https://docs.arcadedb.com/#API-Bolt
- STRATEGY.md DR-11: Decision Records
- HANDOVER §4 Phase 2: Session handover brief