Neo4j vs. relational and other graph databases
|
This section documents the current Neo4j This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, as Neo4j iterates quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
Neo4j is one point in a wider design space: relational engines model relationships as foreign keys resolved at query time, other graph engines store relationships natively but differ in storage architecture and query language, and RDF triple stores model "graph" data in a genuinely different shape. This page compares Neo4j against each.
Index-free adjacency vs. joins, at the mechanism level
A relational join between two tables has no stored notion of "this row is connected to that row." At query
time the engine takes a foreign-key value on one side and performs an index lookup (typically a B-tree
descent, O(log n)) on the other side to find matching rows — and it repeats that lookup once per hop.
A three-hop traversal (friends-of-friends-of-friends) is three chained index lookups, and each one’s cost
grows, however slowly, with the size of the table being probed, not with the size of the actual result.
Neo4j’s storage engine instead gives every node a fixed-size record that holds a direct pointer to its first
relationship record, and every relationship record holds pointers to the next relationship record for each
of its two endpoints — a doubly-linked list per node. Traversing a relationship is dereferencing a pointer:
O(1) regardless of how many other nodes exist in the graph. This is index-free adjacency: no index is
consulted to find a node’s neighbours, because the graph structure itself is the index. Only the entry
point into a traversal (finding the starting node by a property value) uses a conventional index; every hop
after that is pointer-chasing.
// finding the start node uses an index (or a label scan); each -->
// hop after that is a pointer dereference, not a lookup
// https://neo4j.com/docs/getting-started/appendix/graphdb-concepts/
MATCH (p:Person {email: "ada@example.com"})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN DISTINCT fof.name;
The practical consequence: traversal cost in Neo4j scales with the size of the subgraph actually visited, not
with total data volume or hop count, so multi-hop and variable-length patterns
(\(a\)-[:FRIEND*1..5]-\(b\)) stay cheap where the equivalent recursive SQL join keeps re-querying an index
at every level of recursion. See
Neo4j: graph database concepts for the
underlying record format. For guidance on when a graph database is the right choice over a relational one
in the first place — rather than how the two differ mechanically — see
Choosing the Right Database, which also cites Neo4j’s own
graph vs. relational comparison.
Neo4j vs. other property-graph engines
Memgraph, Amazon Neptune and ArangoDB all store relationships natively rather than resolving them through joins, but they differ from Neo4j — and from each other — in storage architecture, query surface and operating model.
| Engine | Storage & query model | Where it diverges from Neo4j |
|---|---|---|
Memgraph |
In-memory-first native graph engine, openCypher-compatible. |
Optimized for low-latency streaming/real-time graph updates over durable, disk-first analytical depth; the GDS algorithm library and clustering maturity are smaller than Neo4j’s. |
Amazon Neptune |
Managed multi-model store supporting both a labeled property graph (openCypher, Gremlin) and RDF (SPARQL) in the same service. |
No standalone deployment — it is AWS-managed only, which trades operational control and on-prem/multi-cloud portability for tight IAM/VPC integration; query-language choice is per-graph, not unified. |
ArangoDB |
Native multi-model document + graph + key/value store, queried with the single language AQL. |
Graph traversal is one feature of a broader multi-model engine rather than the primary design center. It is a reasonable fit when the same data needs document and graph access patterns; a workload that is overwhelmingly graph-shaped keeps a purpose-built engine’s traversal performance and tooling depth (GDS, Bloom, APOC) that a multi-model store spreads thinner. |
// the same pattern is openCypher across Neo4j, Memgraph and Neptune,
// which is what keeps a query portable between them
MATCH (p:Person)-[:FRIEND*1..3]-(fof:Person)
WHERE p.email = "ada@example.com"
RETURN DISTINCT fof.name;
A genuinely different model: RDF and triple stores
RDF triple stores (Apache Jena, Ontotext GraphDB, Amazon Neptune’s RDF mode) are graph databases in name, but their data model is not a labeled property graph:
-
Data shape. Every fact is a subject-predicate-object triple (
\(:ada\) \(:knows\) \(:bob\)). There are no node or relationship properties as first-class citizens — a "property" on an entity is just another triple whose object is a literal, and a relationship that itself needs attributes (Neo4j’s relationship properties, such assinceon:ACTED_IN) must be reified into an intermediate node. -
Query language. SPARQL, not Cypher — pattern-matches triples against a graph pattern and, critically, queries across federated graphs by IRI (
SERVICE <endpoint>) as a native feature. -
Reasoning. RDF’s companion standards, RDFS and OWL, let a reasoner infer new triples from description-logic axioms (subclass, inverse-property, transitivity) before a query even runs — a form of schema-level, standards-based inference that a labeled property graph does not natively provide.
// the same fact in Cypher: a typed, directed relationship with its own property
MATCH (a:Person {name: "Ada"}), (b:Person {name: "Bob"})
CREATE (a)-[:KNOWS {since: date("2020-01-01")}]->(b)
Reach for RDF over Neo4j when the requirement is genuinely semantic-web shaped: open-world data integration across independently published datasets identified by IRIs, standards-mandated OWL/description-logic inference, or interoperability with existing SPARQL endpoints (life sciences ontologies, linked open data). Reach for Neo4j’s labeled property graph when relationships need their own attributes, the query pattern is procedural path-finding and aggregation rather than open-world inference, and the data lives in one organization’s closed-world graph. See Neo4j: graph database concepts for how Neo4j itself frames this distinction.
When to reach for Neo4j specifically
Once a graph database is the right category of tool at all (Choosing the Right Database covers that decision), pick Neo4j specifically, rather than a competitor above, when:
-
The relationships carry their own meaningful data (weights, timestamps, roles) and the workload leans on variable-length and shortest-path traversals — Neo4j’s native
-[:REL*1..5]-andshortestPath\(\(a\)-[*]-\(b\)\)syntax and index-free adjacency are purpose-built for exactly this, more so than a multi-model store’s bolted-on graph layer. -
Graph algorithms — PageRank, community detection, centrality, node embeddings — need to run in the same system as transactional Cypher queries, without exporting the graph elsewhere: the Graph Data Science library runs alongside OLTP workloads on the same store.
-
The team wants Cypher, now standardized as openCypher and converging with ISO GQL, over a vendor-specific or lower-level API such as Gremlin.
-
Operational maturity and ecosystem depth matter: causal clustering, Aura’s managed offering, APOC’s procedure library, and Bloom’s visual exploration are more mature in Neo4j than in the newer native-graph entrants.
-
The deployment needs to run outside a single cloud provider — self-hosted, another cloud, or on-prem — which rules out Neptune’s AWS-only model.
Conversely, prefer Memgraph when sub-millisecond streaming graph updates dominate and deep analytical history is not the point; prefer Neptune when the workload is already deep in AWS and needs either openCypher/Gremlin or SPARQL under one managed service; prefer ArangoDB when the same dataset is genuinely accessed as documents and as a graph and a single query language across both matters more than best-in-class traversal performance; and prefer an RDF store when the requirement is open-world semantic integration or OWL reasoning rather than property-graph traversal.