If you’re building a knowledge graph backend for LlamaIndex, the choice between Neo4j and NebulaGraph comes down to whether you need a mature, single-node property graph with rich tooling or a distributed, horizontally scalable graph that separates compute from storage. Both have first-class LlamaIndex GraphStore implementations, but they optimize for fundamentally different operational profiles. This comparison walks through the concrete trade-offs so you can decide without spinning up both.
Architecture and data model
Neo4j is a native property graph: nodes and relationships both hold key-value properties, and relationships are first-class entities with direction and type. The storage engine uses index-free adjacency — traversing an edge is a pointer chase, not a join. This makes deep traversals (3-5 hops) consistently fast on a single node.
NebulaGraph uses a distributed, shared-nothing architecture with a separate Meta service, Storage service, and Graph service. Data is partitioned across Storage hosts via hash or range partitioning on the vertex ID. Edges are stored twice (out-edge and in-edge) to support bidirectional traversal without a global index. The data model is also a property graph, but schema is enforced at the space level: you define tags (node types) and edge types with explicit property definitions before inserting data.
For LlamaIndex, this schema-on-write requirement matters. Neo4j’s GraphStore implementation can accept arbitrary triples and create nodes/relationships dynamically. NebulaGraph’s integration requires you to pre-create the space, tags, and edge types — or use the NebulaGraphStore helper that attempts schema creation on the fly, which can race in concurrent ingestion pipelines.
# Neo4j: schema-less ingestion works out of the box
from llama_index.graph_stores.neo4j import Neo4jGraphStore
graph_store = Neo4jGraphStore(
username="neo4j",
password="password",
url="bolt://localhost:7687",
database="neo4j"
)
# Just upsert triples; labels and relationship types created implicitly
# NebulaGraph: schema must exist or be created explicitly
from llama_index.graph_stores.nebulagraph import NebulaGraphStore
graph_store = NebulaGraphStore(
space_name="llamaindex",
edge_types=["RELATES"], # must match edge type in schema
rel_prop_names=["weight"], # edge properties
tags=["Entity"], # vertex tags
tag_prop_names=["name"], # vertex properties
address=("127.0.0.1", 9669),
user="root",
password="nebula"
)
LlamaIndex integration maturity
Neo4j’s integration ships in llama-index-graph-stores-neo4j and is maintained by the core team. It supports the full GraphStore interface: upsert_triplet, delete, get, get_rel_map, and structured_query with natural-language-to-Cypher translation via TextToCypherRetriever. The KnowledgeGraphIndex works reliably with entity extraction, and there’s a Neo4jPropertyGraphIndex for the newer property graph abstraction.
NebulaGraph’s integration lives in llama-index-graph-stores-nebulagraph. It implements the same base interface but has gaps: structured_query is not implemented (no Text2nGQL), get_rel_map returns empty results in some versions, and the KnowledgeGraphIndex path requires manual schema alignment. The community maintains it; PRs lag behind LlamaIndex core releases by weeks.
If you’re using the new PropertyGraphIndex (LlamaIndex ≥ 0.10), Neo4j has a dedicated Neo4jPropertyGraphStore with support for hybrid vector+graph retrieval. NebulaGraph does not yet have a property graph store variant — you’re stuck with the legacy KnowledgeGraphIndex path.
Query performance and scaling
Neo4j scales vertically. A well-tuned single instance handles 10M-100M nodes with sub-10ms traversal latency for 2-3 hop queries. Beyond that, you need Neo4j Fabric (sharding) or AuraDS (managed), which adds operational complexity and cost. Read replicas help with throughput but not write scaling.
NebulaGraph scales horizontally by adding Storage hosts. The Graph service is stateless; you scale query throughput by adding Graphd processes. A 3-node cluster (3 Graphd, 3 Storaged, 1 Metad) handles billions of edges with linear write scaling. Traversal latency is higher than Neo4j for small graphs (network hop + partition lookup), but stays flat as data grows.
For typical RAG workloads — entity extraction from 10K-1M documents, then 1-2 hop retrieval — Neo4j’s single-node performance wins on latency. If your knowledge graph grows continuously (ingestion pipeline running daily) and exceeds 50M nodes, NebulaGraph’s horizontal scaling becomes the only viable option without sharding logic in your application.
// Neo4j: 2-hop neighborhood, returns in ~2ms on 10M nodes
MATCH (e:Entity {name: $entity})-[r1]-(n1)-[r2]-(n2)
RETURN n1, r1, n2, r2 LIMIT 50
// NebulaGraph: equivalent 2-hop, ~8-15ms on same data in 3-node cluster
MATCH (v:Entity {name: $entity}) -[e1]-> (v1) -[e2]-> (v2)
RETURN v1, e1, v2, e2 LIMIT 50
Operational complexity
Neo4j runs as a single process (or a causal cluster of 3-7 nodes). Backup is neo4j-admin dump or online backup to S3. Monitoring is standard: JMX/Prometheus exporter, logs, transaction logs. Upgrades are in-place. The operational surface area is small.
NebulaGraph runs three distinct services: Metad (metadata, RAFT consensus), Storaged (data, RAFT per partition), Graphd (stateless query). You need at least 3 Metad for HA, 3 Storaged for replication factor 3, and 2+ Graphd for query HA. That’s 8+ processes minimum. Backup requires nebula-br (backup & restore tool) with a separate meta backup. Upgrades are rolling but must respect version compatibility across services. Monitoring requires scraping each component separately.
If your team has Kubernetes operators or managed service experience, NebulaGraph is manageable. If you want “install, configure, forget,” Neo4j wins. The managed offerings reflect this: Neo4j Aura is a mature DBaaS; NebulaGraph Cloud exists but is earlier stage.
Cost model
Neo4j Community Edition is free (GPLv3) for single-node. Enterprise Edition (clustering, LDAP, encryption at rest) requires a commercial license — typically $50K-200K/year depending on core count and support tier. AuraDS (managed) starts around $0.30/hour for a 4 vCPU/16GB instance, scaling to $3-5/hour for production clusters.
NebulaGraph is Apache 2.0 — fully open source, no enterprise tier. You pay for infrastructure only. A 3-node cluster on AWS (3× r6g.xlarge for Storage, 3× c6g.large for Graphd, 3× t3.medium for Metad) runs ~$1,200/month on-demand. Reserved instances cut that ~40%. No license fees at any scale.
For teams with existing cloud spend commitments, NebulaGraph’s pure-infrastructure cost is attractive. For teams who’d rather pay a vendor to handle operations, Neo4j Aura’s premium includes expertise you’d otherwise hire.
Ecosystem and tooling
Neo4j’s ecosystem is unmatched: Bloom (visual exploration), Graph Data Science library (70+ algorithms), Neo4j Browser, Cypher Shell, drivers for 12+ languages, extensive documentation, and a 15-year community. The LlamaIndex integration benefits from this — when something breaks, someone has seen it.
NebulaGraph has NebulaGraph Studio (web UI), NebulaGraph Explorer (visualization), nGQL (SQL-like but distinct), and growing algorithm library (PageRank, Louvain, etc.). The community is active but smaller — Slack ~3K members vs Neo4j’s ~50K. Documentation has improved significantly in v3.x but still has gaps on advanced tuning.
For LlamaIndex specifically, the Neo4j integration has more examples, better error messages, and faster issue resolution. NebulaGraph’s integration works but expects you to read the source when things go wrong.
Comparison table
| Dimension | Neo4j | NebulaGraph |
|---|---|---|
| Data model | Property graph, schema-on-read | Property graph, schema-on-write |
| Scaling | Vertical + Fabric sharding | Horizontal (shared-nothing) |
| LlamaIndex integration | Core-maintained, full interface | Community, gaps in PropertyGraphIndex |
| Text-to-query | TextToCypherRetriever (mature) | Not implemented |
| Single-node latency (2-hop) | 1-5ms | 8-20ms (network overhead) |
| Write throughput ceiling | ~50K ops/sec (single node) | Linear with Storage hosts |
| Operational processes | 1 (or 3-7 cluster) | 8+ minimum for HA |
| License | GPLv3 (Community) / Commercial (Enterprise) | Apache 2.0 |
| Managed offering | Aura (mature DBaaS) | NebulaGraph Cloud (early) |
| Visualization | Bloom, Browser | Studio, Explorer |
| Best for | <50M nodes, low-latency RAG, team wants managed | >50M nodes, continuous ingestion, infrastructure-first team |
Which to choose
Choose Neo4j if:
- Your knowledge graph stays under 50M nodes and you need sub-10ms retrieval latency for 1-3 hop queries.
- You want the
PropertyGraphIndexwith hybrid vector+graph retrieval — it’s production-ready on Neo4j today. - Your team prefers a managed service (Aura) or a single binary to operate.
- You need Text2Cypher for natural language graph queries without writing a custom retriever.
- You rely on graph algorithms (community detection, centrality) via GDS — the library is mature and well-documented.
Choose NebulaGraph if:
- Your ingestion pipeline adds millions of nodes/edges daily and you’ve hit or will hit single-node write limits.
- You need horizontal write scaling without implementing application-level sharding.
- Your infrastructure team is comfortable operating distributed systems (Kubernetes, RAFT, multi-service deployments).
- You want zero license cost at any scale and have cloud commit spend to burn.
- You can live with the legacy
KnowledgeGraphIndexpath or are willing to contribute to thePropertyGraphStoreimplementation.
The pragmatic middle ground: Start with Neo4j Community on a single node. The migration path to NebulaGraph later is non-trivial (different query language, schema model, tooling), but most RAG projects never outgrow a well-provisioned Neo4j instance. If you’re building a multi-tenant graph platform with unbounded growth, provision NebulaGraph from day one — the operational investment pays off at scale.
If you’re routing LLM traffic across multiple providers for your graph-RAG pipeline, n4n.ai’s single endpoint handles fallback and per-token metering so your ingestion stays online when one provider degrades.