Neo4j vs CosmosDB, when used as a graph database

Ondrej Kvasnovsky
11 min readOct 3, 2024

--

Azure Cosmos DB is a multi-model database service that supports various data models, including key-value, column-family, document, and graph. Its graph model is based on the Gremlin API, which allows Cosmos DB to store and query graph data. While Cosmos DB can handle graph data, it is not a native graph database like Neo4j.

Here’s how Cosmos DB differs from Neo4j, and some of the disadvantages of Cosmos DB compared to Neo4j when used as a graph database:

1. Native Graph Database:

  • Neo4j: Neo4j is a native graph database built specifically for graph data and queries. It uses a graph engine that is optimized for handling nodes, relationships, and graph-specific queries. It provides deep graph traversal capabilities, pathfinding, and advanced graph algorithms.
  • Cosmos DB: Cosmos DB is a multi-model database where the graph model is one of the supported models. It is not purpose-built for graphs and is, therefore, less optimized for graph-specific use cases compared to Neo4j.

2. Graph Query Language:

  • Neo4j: Neo4j uses Cypher, a powerful query language designed specifically for graph operations. Cypher is expressive and optimized for graph traversals, pattern matching, and relationship-centric queries.
  • Cosmos DB: Cosmos DB uses the Gremlin query language for graph operations. While Gremlin is also a graph traversal language, it is more general and less expressive compared to Cypher, especially for complex graph queries. Neo4j’s Cypher language often allows for simpler, more readable graph queries.

3. Performance and Scalability:

  • Neo4j: Neo4j’s native graph processing engine is highly optimized for complex graph traversals and deep pathfinding. It can perform better for queries that involve multiple hops across a graph, as it directly manages relationships between nodes.
  • Cosmos DB: Cosmos DB is designed for global distribution and multi-model data rather than graph-specific optimizations. Graph traversals in Cosmos DB might be slower for deep, multi-hop queries compared to Neo4j because it lacks Neo4j’s graph-optimized storage engine.

4. Graph-Specific Features:

  • Neo4j: Offers a rich set of graph algorithms (like shortest path, PageRank, community detection) and built-in tools for data visualization, making it very suitable for complex graph analysis and graph data science. Neo4j can be used as RAG (Retrieval Augmented Generation), see https://neo4j.com/developer-blog/advanced-rag-strategies-neo4j for more information.
  • Cosmos DB: Focuses on general-purpose features and does not offer the same depth in terms of built-in graph algorithms or visualization tools.

5. ACID Transactions:

  • Neo4j: Supports full ACID transactions for graph operations, which ensures strong consistency across graph data operations.
  • Cosmos DB: Cosmos DB offers multi-model ACID transactions at the partition level but may not provide the same level of fine-grained ACID transaction support for graph-specific operations as Neo4j does, especially when transactions span multiple partitions.

6. Community and Ecosystem:

  • Neo4j: Has a large, specialized community focused on graph use cases. Its ecosystem includes tools for graph visualization, analytics, and integrations tailored for graph data processing.
  • Cosmos DB: Has a broad Azure and multi-model ecosystem but lacks the same level of focus on graph-specific tools and libraries that Neo4j offers.

7. Cost and Pricing:

  • Neo4j: Pricing for Neo4j depends on the deployment model (self-hosted, cloud, etc.), and for large graphs, it may involve costs related to high memory and CPU usage due to its graph-centric optimizations.
  • Cosmos DB: Cosmos DB pricing is based on Request Units (RUs) and storage consumption, which can scale well for distributed applications but may become more expensive for graph use cases with many deep graph traversals, as these can be resource-intensive.

Key Disadvantages of Cosmos DB vs Neo4j for Graph Use Cases:

  1. Less optimized for complex graph operations: Cosmos DB’s multi-model nature makes it less efficient for deep graph traversals and large graph queries.
  2. Gremlin vs Cypher: Cypher, Neo4j’s query language, is more user-friendly and powerful for graph-specific queries than Cosmos DB’s Gremlin.
  3. Graph-specific algorithms and analytics: Neo4j has a rich set of built-in graph algorithms and tools for advanced graph analysis, which are absent or less developed in Cosmos DB.
  4. Performance: Cosmos DB is designed for scalability across multiple data models, which can result in lower performance compared to Neo4j for graph-specific operations.
  5. Cost for graph operations: Cosmos DB’s pricing model based on RUs can make deep graph traversals more expensive, especially for large or complex graphs.

When to Use Cosmos DB vs Neo4j:

  • Cosmos DB: Better if you need a multi-model, globally distributed database that can handle multiple data types (documents, key-value, column-family, and graphs) with good scalability across various regions.
  • Neo4j: Better if you need a highly optimized, purpose-built graph database for complex graph traversals, graph analytics, and deep relationship queries.

Cosmos DB approach to implement graph-like DB

Azure Cosmos DB is not a native graph database; however, it is turned into a graph database by supporting a graph data model and the Gremlin API, which enables graph-based operations. Here’s an explanation of how Cosmos DB functions as a graph database:

1. Multi-Model Architecture:

Azure Cosmos DB is designed as a multi-model database, meaning it can handle various types of data models (key-value, document, column-family, and graph). Each of these models is implemented over a common storage engine and distribution architecture, which provides high availability, global distribution, and scalability. For the graph model, Cosmos DB supports the property graph model using the Gremlin API.

2. Property Graph Model:

  • Nodes and Edges: In a graph database, you typically have nodes (vertices) representing entities and edges representing relationships between those entities. Each node and edge can have properties, key-value pairs that describe their characteristics.
  • In Cosmos DB, the graph data model follows this property graph structure. Nodes (vertices) and edges are stored as documents in the underlying document database. Each document stores properties and metadata (such as edge relationships).

3. Gremlin API Support:

Cosmos DB uses the Gremlin API, which is part of the Apache TinkerPop framework, to support graph database operations. Gremlin is a query language for traversing and querying graph data.

  • The Gremlin API in Cosmos DB allows users to create vertices (nodes), edges (relationships), and run graph queries like traversals.
  • Gremlin enables users to write queries to traverse the graph, look for patterns, and analyze relationships between nodes. Queries can involve operations like pathfinding, multi-hop traversal, or pattern matching.

4. Document Storage for Graph Data:

Even though Cosmos DB exposes a graph API via Gremlin, it internally stores graph data in the same format as it stores documents in the document model:

  • Vertices (Nodes) are stored as documents (JSON objects). Each vertex document contains properties like the node’s ID, labels, and attributes.
  • Edges (Relationships) are also stored as documents. Each edge document includes metadata about the vertices it connects (from-to references), the edge’s properties, and information like the edge’s ID and label.

For example, here is a node representing a Person and how it is stored as a JSON document:

{
"id": "1234",
"label": "Person",
"name": "Alice",
"age": 30,
"partitionKey": "person_partition"
}

Here is an edge representing a Friendship relationship between two people:

{
"id": "5678",
"label": "Friend",
"fromVertexId": "1234",
"toVertexId": "5679",
"since": "2021",
"partitionKey": "edge_partition"
}

5. Partitioning and Scaling:

Cosmos DB is built with horizontal scalability in mind, and this applies to graph data as well.

  • Partitioning is used to distribute data across multiple servers to allow for scalability. Both vertices and edges are assigned partition keys to ensure data is distributed and can be efficiently retrieved.
  • However, the partitioning model is not specifically optimized for graph traversals. While Cosmos DB can scale well horizontally for graph operations, cross-partition traversals (where graph data spans multiple partitions) may lead to performance bottlenecks, as traversals that span partitions require network communication and coordination between partitions.

6. Consistency and Global Distribution:

Cosmos DB offers five consistency levels: strong, bounded staleness, session, consistent prefix, and eventual consistency. This consistency model applies to graph operations as well.

  • Global distribution capabilities allow for graph data to be distributed across multiple geographic regions, which is beneficial for applications requiring low-latency access to graph data from various locations.
  • However, this comes at the cost of more complex handling of graph traversals across regions if the data is partitioned geographically.

7. Gremlin Traversals and Query Execution:

When users run a graph traversal query via the Gremlin API, Cosmos DB translates the Gremlin query into internal document-based queries that operate on the underlying document storage.

For example, a query like this looks for vertices labeled Person with the name “Alice”, traverses outgoing Friend edges, and returns the names of connected vertices:

g
.V()
.hasLabel("Person")
.has("name", "Alice")
.out("Friend")
.values("name")

Cosmos DB processes the query by translating the Gremlin traversal into document queries that retrieve vertex and edge documents, then performs the traversal based on the relationships stored in the documents.

8. Indexing:

Cosmos DB automatically indexes graph data (vertices and edges) to improve query performance. However, indexing in Cosmos DB is not graph-specific. It indexes documents based on their properties, but it does not perform graph-aware optimizations like Neo4j’s native graph indexing, which can be more efficient for traversals.

Key Differences from Neo4j:

  • Storage Engine: Neo4j uses a native graph storage engine that is optimized for graph data and operations, storing relationships explicitly as first-class entities. In contrast, Cosmos DB stores graph data as documents in a general-purpose storage engine.
  • Traversal Efficiency: Neo4j can directly traverse relationships between nodes using pointer-based references, making deep graph traversals more efficient. In Cosmos DB, relationships are represented indirectly via document-based edges, which require additional lookup operations, especially when data spans partitions.
  • Optimized Graph Operations: Neo4j is optimized for graph-specific operations like pattern matching, shortest path algorithms, and graph analytics. Cosmos DB, while supporting graph data, lacks native optimizations for these advanced graph operations.

How is Neo4j designed

Neo4j is a native graph database, which means it is purpose-built to store, manage, and query graph data efficiently. Its technical architecture is highly optimized for graph operations, such as traversals and relationship-based queries, making it more suitable for tasks involving complex relationships, recommendation systems, and graph analytics.

Let’s break down Neo4j’s architectural features that make it superior to Azure Cosmos DB for graph use cases.

1. Native Graph Storage Engine:

Neo4j uses a native graph storage model, meaning it is designed to store nodes, relationships, and properties directly in a way that optimizes for graph traversal. In contrast, Cosmos DB uses a document-based storage model (even for graphs), where relationships are stored as documents, requiring lookups to traverse them.

Neo4j native graph storage consists of:

  • Nodes and relationships are first-class citizens: Neo4j stores nodes (vertices) and relationships (edges) explicitly. Each node and relationship has a direct pointer (a reference) to the next node or relationship in the graph.
  • Pointer-based traversals: Relationships between nodes are represented as pointers (memory addresses), so traversing from one node to another is highly efficient. There’s no need to query external documents or tables.
  • Compact storage: Neo4j compresses graph structures using a linked-list approach where nodes and relationships are stored in a compact, connected way, which minimizes storage overhead and speeds up traversal.

This contrasts with Cosmos DB’s Gremlin API, where traversals require fetching related documents, leading to slower performance.

2. Efficient Traversal and Graph Querying:

Neo4j’s query execution engine is designed for fast traversal of graphs, which is critical for graph-centric use cases like recommendation engines or network analysis. This traversal capability is essential for applications that perform deep graph traversals involving multiple “hops” (e.g., friend-of-a-friend, recommendation algorithms).

  • Fast in-memory traversals: Neo4j optimizes for in-memory processing of graph data, so traversals are done without hitting disk frequently. This enables quick exploration of complex, multi-hop relationships between nodes.
  • Traversal performance: Neo4j can execute traversals by following the direct pointer-based connections, rather than performing expensive index lookups (as in Cosmos DB) or document queries. This significantly improves the performance of deep graph queries.

3. Cypher Query Language:

Neo4j’s Cypher is a highly expressive and specialized query language for graphs. It is designed specifically for graph pattern matching and querying relationships, making it much more intuitive and powerful than Gremlin, which Cosmos DB uses.

Pattern matching: Cypher allows you to easily describe and match graph patterns using an ASCII-like syntax. This is especially useful for expressing complex queries involving multiple nodes and relationships.

MATCH (user:Person)-[:FRIEND_OF]->(friend)-[:LIKES]->(movie:Movie) 
RETURN movie.titl

This query finds movies liked by friends of a particular user in a very natural and efficient way.

Cypher is more expressive for complex graph queries compared to Gremlin, which relies on more procedural-style traversals. Cypher’s declarative nature makes it easier to express complex queries, and the Neo4j engine optimizes their execution under the hood.

4. Index-Free Adjacency:

One of the key architectural principles of Neo4j is index-free adjacency, which is core to its performance and scalability in graph operations.

What is index-free adjacency? In Neo4j, each node directly references its adjacent nodes through pointers, without needing to look up any index. When traversing relationships, Neo4j does not need to consult an index to determine which nodes are connected — it can directly follow the references.

This allows Neo4j to traverse millions of nodes and relationships quickly because it avoids the overhead of index lookups. In contrast, Cosmos DB relies on indexes to locate related documents, which introduces significant overhead for graph traversals, especially when dealing with large datasets or deep traversals.

5. Built-in Graph Algorithms:

Neo4j comes with a comprehensive library of graph algorithms that are critical for many graph use cases, especially in Recommendation and Analysis Graph (RAG) scenarios.

Examples of algorithms: Neo4j has optimized implementations of algorithms like PageRank, shortest path, community detection, graph clustering, and more. These algorithms are key to performing tasks like:

  • Finding influential nodes (e.g., in social networks).
  • Identifying communities and clusters in large datasets.
  • Recommending products or users based on graph patterns.

Graph Data Science (GDS): Neo4j’s GDS library is designed for advanced analytics and machine learning on graph data. This library provides highly optimized, parallelized implementations of algorithms that are often used in recommendation systems and large-scale analysis.

Cosmos DB does not provide built-in support for graph algorithms, meaning these would need to be implemented manually or rely on external processing frameworks, making it more cumbersome and less performant for RAG use cases.

6. Relationship-Centric Design:

In Neo4j, relationships are first-class citizens and are optimized for both storage and querying. Each relationship stores directionality and can have multiple properties, enabling efficient querying based on both the relationship type and properties.

  • Efficient filtering: Because relationships are stored natively, Neo4j can efficiently filter queries based on specific types of relationships or properties of those relationships without additional overhead.
  • Graph-oriented indexing: Neo4j provides relationship-aware indexing, which optimizes both nodes and relationships for graph queries, reducing query execution times for complex graph patterns. This is crucial in scenarios like fraud detection or recommendation engines, where relationships play a central role.

In Cosmos DB, relationships are stored as external documents, which introduces a layer of complexity and inefficiency, especially when querying based on relationships or traversing complex structures.

7. Graph-Aware Partitioning and Sharding:

Neo4j, especially in its Enterprise Edition, supports graph sharding for large-scale, distributed graph deployments. It is designed to partition graphs in a way that preserves the locality of relationships, minimizing the need for cross-shard or cross-cluster communication.

Graph partitioning: Neo4j partitions graphs based on relationships, ensuring that related nodes are often stored on the same shard or in close proximity. This significantly reduces the cost of traversals and cross-partition queries.

Scalability: Neo4j’s clustering and replication support horizontal scaling while maintaining high performance for large graphs. Its partitioning strategy is more relationship-aware, leading to better performance for graph-centric queries compared to Cosmos DB’s general-purpose partitioning, which is not designed for graphs.

8. High Availability and Clustering:

Neo4j’s Enterprise Edition includes features for clustering, replication, and high availability, making it suitable for mission-critical applications. Neo4j’s cluster architecture is designed to handle large graphs while ensuring fast failover, load balancing, and disaster recovery.

Read replicas: Neo4j supports read replicas that can offload query workloads, allowing the system to scale horizontally while maintaining fast query performance.

Graph-aware load balancing: Neo4j’s clustering takes graph structure into account when distributing workloads, ensuring that graph queries are efficiently handled by the appropriate nodes in the cluster.

9. Transaction Management and ACID Compliance:

Neo4j is fully ACID-compliant, meaning it ensures strong transactional guarantees even in the presence of concurrent operations. This is critical for applications that need consistent and reliable graph updates, such as fraud detection, recommendation engines, and financial systems.

Optimized transactions: Neo4j’s transactions are optimized for graph operations, with support for fine-grained locking at the node and relationship level, ensuring high concurrency while maintaining data consistency.

Multi-phase commit: For distributed transactions, Neo4j uses a multi-phase commit protocol to ensure that updates are applied consistently across nodes in a cluster.

--

--