Graph DB best practices — Neo4j & Memgraph

Source: 106-agent deep-research workflow (session 242, 2026-07-21), findings adversarially verified (3-vote refutation). Full report with citations: reports/research-graph-db-best-practices.md in the orchestrata-ultimate repo.

Neo4j (operational KG, 10.53.1.11, ~800k nodes)

  1. Every property predicate needs a label to use an index. Property indexes are label-scoped; MATCH (n) WHERE n.prop = $x full-scans the node store. Measured here: ~260ms per sweep on 803,688 nodes vs ~6ms label-bounded. Two built-in token-lookup indexes serve bare label scans.
  2. RANGE indexes support STARTS WITH (used for the Session session_id prefix seeks); TEXT indexes are the right tool for CONTAINS / ENDS WITH — candidates here: Session.session_id, code-intelligence qualname lookups.
  3. PROFILE, not EXPLAIN, for real db-hits; plan cache makes the first parameterized run pay compile cost — keep queries parameterized so the cache hits.
  4. Without GDS Enterprise: shortest-path (shortestPath() / apoc.path) is native; PageRank/community-detection/betweenness need GDS Community (free, ALL algorithms, 4-core cap, in-memory projections) — worth installing for the code-intelligence graph.
  5. Page cache sizing: keep the store fully memory-resident (store ≈ few GB here; check server.memory.pagecache.size).

Memgraph (shared semantic/RAG graph, orchgraph HA)

  1. storage.access_timeout_sec default 1s is too tight under concurrent access — a reader polling during a bulk write aborts the writer. APPLIED: 60s at all 3 layers (runtime SET DATABASE SETTING on both data instances, persistent systemd units via incus file push, rebuild template infra/rehearsal/provision_node.sh).
  2. Index creation scans the entire vertex store even for an empty label (2,514ms measured). Never create per-test/per-batch indexes; create once, isolate by data.
  3. IN_MEMORY_ANALYTICAL is bulk-load-only here — it is incompatible with replication/HA, so the Raft cluster must stay IN_MEMORY_TRANSACTIONAL; analytical mode is only for offline single-node rebuilds.
  4. HNSW vector search: deleted vertices can surface as "Returning a deleted object" for a settle window (>10s, survives sessions) — treat deletes under a live vector index as unsafe mid-workload; prefer tombstoning or end-of-run cleanup. Tune m/ef_construction at index creation, ef (search) per query.
  5. MAGE algorithms are fully available in community (PageRank, Louvain, betweenness, etc. as query modules) — the semantic graph can run GraphRAG-adjacent analytics without any license.

Actionable items for this stack

# Item Status
1 Memgraph access timeout 1s → 60s (3 layers) DEPLOYED
2 Label-bounded sweeps (tests) + label-scoped production search (_contains_search, QueryEngine.search) DONE (d1c6733a, 9c5cc9d3, ffbb1a91)
3 TEXT indexes for CONTAINS lookups (Class/Function/Predicate name) DEPLOYED (all 4 DBs, ffbb1a91)
4 GDS Community 2.13.2 on neo4j-db (PageRank on CALLS: proj 1.43s, PR 0.33s) DEPLOYED (698b0845)
5 Page-cache/heap sizing (256M/512M → 2g/1g primary, 1g/1g workers) DEPLOYED (rolling restart verified)
6 Orchgraph fork: concurrent/online index build patch check backlogged

Related: Running the test suite · Suite speedup story · Graph databases (concepts)