Back to Blog

Graph OLAP Engine: The Fastest Graph Analytics with Zero Compromises

ArcadeDB Graph OLAP Engine

ArcadeDB has always been the fastest OLTP graph database. But we asked ourselves: what if we could make analytical queries — PageRank, connected components, multi-hop traversals — up to 462x faster, without giving up a single byte of transactional performance?

With ArcadeDB v26.3.2, we’re introducing the Graph OLAP Engine — and the answer is yes. Zero compromises.

The Problem with OLTP for Analytics

ArcadeDB’s OLTP engine is built for speed: point lookups, single-record mutations, ACID transactions — it handles all of this faster than any other graph database. But analytical workloads are a different beast. When you run PageRank or community detection, you’re accessing millions of edges in tight loops. The row-oriented, pointer-chasing nature of OLTP storage hits three walls:

  • Cache misses: every edge lookup follows a RID pointer to a different page in memory
  • Object overhead: every vertex and edge is a Java object with ~48 bytes of overhead
  • GC pressure: traversals create millions of short-lived objects that hammer the garbage collector

These are fundamental limitations of any OLTP storage engine, not just ours. The traditional answer has been to export your data to a separate analytics system. We think that’s unacceptable.

Graph Analytical Views: OLAP That Lives Inside Your Database

The Graph OLAP Engine introduces Graph Analytical Views (GAV) — a read-optimized, columnar representation of your graph that lives alongside your live OLTP data. You create a view, and the engine keeps it synchronized with every write.

Here’s how simple it is:

CREATE GRAPH ANALYTICAL VIEW social
  VERTEX TYPES (Person, Company)
  EDGE TYPES (FOLLOWS, WORKS_AT)
  PROPERTIES (name, age, status)
  UPDATE MODE SYNCHRONOUS

Or if you want a view over your entire graph:

CREATE GRAPH ANALYTICAL VIEW fullGraph

That’s it. From this moment on, your Cypher and SQL queries are automatically accelerated by the OLAP engine. No query changes needed — the optimizer detects the GAV and transparently substitutes OLTP traversal operators with CSR-based ones.

How It Works Under the Hood

Compressed Sparse Row (CSR) Encoding

Instead of pointer-chasing through pages, the OLAP engine encodes your entire graph topology as flat int[] arrays using CSR encoding:

Forward CSR (outgoing edges):
  offsets:   [0, 3, 5, 8, ...]     ← one entry per vertex + sentinel
  neighbors: [1, 5, 7, 2, 6, ...]  ← dense neighbor IDs, contiguous per source

  Neighbors of vertex v = neighbors[offsets[v] .. offsets[v+1])
  Out-degree of vertex v = offsets[v+1] - offsets[v]   ← O(1)

Both forward (OUT) and backward (IN) CSR indexes are maintained for bidirectional traversal. This layout is cache-line friendly — sequential memory access means the CPU prefetcher does the work for you. Zero object allocation during traversal. SIMD-friendly vectorized operations.

Columnar Property Storage

Properties are stored as typed flat arrays — int[], long[], double[], or dictionary-encoded int[] for strings. Each column has a compact null bitmap using just 1 bit per vertex. Dictionary encoding achieves near-100% compression for low-cardinality fields like status, category, or tag.

Three Synchronization Modes

The key design decision was making the OLAP engine coexist with OLTP, not replace it. You choose how writes propagate:

Mode Behavior Staleness Best For
SYNCHRONOUS Applies overlay on each commit Zero — writes reflected immediately Real-time analytics
ASYNCHRONOUS Background rebuild on commit Brief window during rebuild Large graphs, eventual consistency
OFF Manual rebuild only Until you rebuild Batch analytics, static snapshots

In SYNCHRONOUS mode, the engine captures transaction deltas and merges them into an immutable overlay on top of the base CSR. Readers always see a consistent snapshot via volatile reference swap. When the overlay grows past a configurable threshold (default: 10,000 edges), a background compaction rebuilds the full CSR — transparently, with no downtime.

The Benchmarks

Internal Benchmark: OLTP vs OLAP

Graph: 500K vertices, ~8M edges

Benchmark ArcadeDB OLTP ArcadeDB OLAP Speedup
1-hop count 3.0 µs 0.8 µs 3.8x
1-hop IDs 5.0 µs 1.0 µs 5.1x
2-hop 31.3 µs 3.3 µs 9.4x
3-hop 418.3 µs 35.1 µs 11.9x
4-hop 6,089 µs 390.1 µs 15.6x
5-hop 92,497 µs 2,765 µs 33.5x
Shortest Path 165 ms/pair 3.1 ms/pair 54.0x
PageRank (20 iter) 54,094 ms 117 ms 462.3x
Connected Components 2,238 ms 60 ms 37.3x
Label Propagation 33,450 ms 142 ms 235.6x

Benchmarked on a MacBook Pro M5 Pro (2026), 48 GB RAM, 1 TB disk.

The OLAP engine dominates across the board, especially on full-graph algorithms. PageRank goes from nearly a minute to 117 milliseconds — a 462.3x speedup. Connected Components is 37.3x faster, and Label Propagation 235.6x faster. The deeper the traversal, the bigger the advantage.

LDBC Graphalytics: ArcadeDB vs the Competition

We ran the standard LDBC Graphalytics benchmark framework against other graph databases. Results include both embedded mode (in-process Java) and Docker container (same conditions as Neo4j, Memgraph, FalkorDB, and HugeGraph). The results speak for themselves:

Algorithm ArcadeDB Embedded ArcadeDB Docker Neo4j 2026 Kuzu DuckPGQ ArangoDB FalkorDB HugeGraph Winner
Load 55.34s 35.30s 653.41s 3.56s 0.35s 352.47s 1568.36s 15.27s DuckPGQ
PageRank 0.10s 0.40s 3.50s 0.97s 0.83s 47.58s 0.70s 1.23s ArcadeDB
WCC 0.08s 0.17s 0.32s 0.10s 1.95s 25.83s 0.58s 2.00s ArcadeDB
BFS 0.09s 0.30s 0.58s 0.29s N/A N/A 0.05s 0.17s FalkorDB
LCC 2.35s 2.51s 15.47s N/A 10.79s N/A N/A 122.44s ArcadeDB
SSSP 0.92s 0.41s N/A N/A N/A 33.36s N/A N/A ArcadeDB
CDLP 1.11s 1.35s N/A N/A N/A 126.63s 1.58s 23.88s ArcadeDB

ArcadeDB leads on 5 out of 6 algorithms — both in embedded mode and as a Docker container. The only exception is BFS, where FalkorDB edges ahead (0.05s vs 0.09s). Even running as a Docker container — with network serialization overhead, HTTP API, and Docker Desktop’s VM layer — ArcadeDB remains the fastest on every other algorithm. The Docker results are measured warm (JIT-compiled), matching how production servers run. Results are fully reproducible — see the benchmark project on GitHub.

Memgraph crashed on connected components. Investigating further, we found 50 open issues on their GitHub reporting random crashes triggered even by simple queries, some of which have remained unaddressed for over 3 years.

LSQB: Subgraph Pattern Matching

We also ran the LSQB (Labelled Subgraph Query Benchmark) — a microbenchmark from the LDBC council that focuses on subgraph pattern matching: counting how many times a given labelled graph pattern appears in a dataset. It tests multi-way joins, anti-patterns (NOT EXISTS), and complex multi-hop chains using 9 Cypher queries on the LDBC SNB social network (SF1: ~3.9M vertices, ~17.9M edges).

We compared ArcadeDB against 7 other systems — graph databases (Kuzu, Neo4j, Memgraph, Dgraph), relational engines (DuckDB, PostgreSQL), and ArcadeDB itself as a Docker container. All Docker-based systems run under the same conditions (Docker Desktop for macOS):

Query Pattern Expected Count ArcadeDB Embedded ArcadeDB Docker DuckDB Kuzu Neo4j PostgreSQL Memgraph Dgraph Winner
Q1 8-hop chain 221,636,419 0.23s 0.25s 0.15s 5.83s 8.25s 6.56s 60.45s 2.52s DuckDB
Q2 Diamond 1,085,627 0.18s 0.19s 0.02s 0.14s 2.06s 0.34s timeout N/A DuckDB
Q3 Triangle 753,570 0.10s 0.13s 0.05s 2.44s 14.31s 2.12s timeout N/A DuckDB
Q4 Star join 14,836,038 0.03s 0.03s 0.08s N/A 7.82s 6.86s 4.50s 8.13s ArcadeDB
Q5 Fork 13,824,510 0.29s 0.23s 0.04s N/A 6.72s 0.69s 3.86s N/A DuckDB
Q6 2-hop traversal 1,668,134,320 0.11s 0.11s 2.18s 1.41s 52.06s 17.72s 148.14s N/A ArcadeDB
Q7 Star (optional) 26,190,133 0.09s 0.02s 0.08s N/A 10.45s 11.22s 5.59s 5.97s ArcadeDB
Q8 Anti-pattern 6,907,213 0.19s 0.19s 0.07s N/A 12.91s 1.31s 3.37s N/A DuckDB
Q9 Anti-pattern + traversal 1,596,153,418 1.18s 1.06s 7.77s 6.15s 59.09s 22.25s timeout N/A ArcadeDB

All 9 queries produce correct results matching the official LSQB expected output. Kuzu skips Q4/Q5/Q7/Q8 (no :Message supertype support). Memgraph times out on Q2/Q3/Q9 (600s limit).

ArcadeDB is the fastest system on 4 out of 9 queries (Q4, Q6, Q7, Q9). Q4 and Q7 are star-shaped joins centered on a Message node — with the GAV’s CSR acceleration, ArcadeDB completes these in 10–30ms, 3–8x faster than DuckDB and 261–1045x faster than Neo4j. Q6 and Q9 are multi-hop path traversals where ArcadeDB is 7–20x faster than DuckDB, 55–473x faster than Neo4j, and 21–161x faster than PostgreSQL. Q6 in particular showcases the edge-scan algebraic optimization: ArcadeDB computes the 1.67-billion-row count in just 110ms — 20x faster than DuckDB.

Where DuckDB wins: The remaining queries (Q1, Q2, Q3, Q5, Q8) are join-intensive patterns — long chains, diamonds, forks, and anti-patterns — where DuckDB’s columnar vectorized execution excels. However, the gap has narrowed significantly: Q8 is now only 2.7x slower than DuckDB (down from 7.7x), thanks to the edge-scan anti-join optimization.

ArcadeDB Docker vs other Docker systems (apples-to-apples): Even with HTTP + network + Docker VM overhead, ArcadeDB Docker is 10–1045x faster than Neo4j, 2–24x faster than PostgreSQL, and 5–559x faster than Memgraph on the queries Memgraph completes. The Docker overhead is minimal (0.01–1.08s) because the GAV/CSR does the heavy lifting, not the transport.

The other graph databases: Neo4j is 10–1045x slower than ArcadeDB on every query. Memgraph times out on 3 queries and is 5–559x slower on the ones it completes. Kuzu can’t run 4 of 9 queries due to missing type hierarchy support, and is 2–28x slower than ArcadeDB on most of the rest (though Kuzu edges ahead on Q2 at 0.14s vs 0.18s). PostgreSQL is faster than all other graph databases but still 2–161x slower than ArcadeDB.

Dgraph v25.3.0 has no native pattern matching language (DQL is a hierarchical traversal language, not Cypher/SQL). Through creative use of DQL value-variable propagation and math(), we managed to express 3 of 9 queries — but Dgraph is 11x slower than ArcadeDB on Q1 (2.52s vs 0.23s), 271x slower on Q4 (8.13s vs 0.03s), and 597x slower on Q7 (5.97s vs 0.01s). The remaining 6 queries are fundamentally impossible in DQL (no JOINs, no self-joins, no anti-joins).

SurrealDB v2.6.4 fares even worse: queries are written for 5 of 9 patterns using nested subqueries with $parent dereferencing, but every single one times out at 120 seconds. The O(n*m) nested loop execution without index acceleration is simply too slow for 3.9M vertices. The remaining 4 queries cannot be expressed in SurrealQL at all (no table aliases for self-joins).

The takeaway: ArcadeDB’s CSR engine beats every other graph database on every single query except Q2 where Kuzu is marginally faster — both embedded and as a Docker container — and beats DuckDB on the graph-shaped queries. Databases that claim “graph capabilities” (Dgraph, SurrealDB) can barely express these patterns, let alone execute them competitively. And unlike DuckDB, ArcadeDB gives you ACID transactions, persistence, concurrent access, and a full graph query language on top.

Memory: Compact by Design

You might expect an OLAP layer to be a memory hog. The opposite is true. For the 500K vertex / 8M edge benchmark graph:

  • GAV (OLAP): 138.4 MB
  • OLTP estimate: ~1.2 GB
  • Compression ratio: 9.0x more compact

The CSR encoding uses ~8 bytes per edge, node ID mapping takes ~8 bytes per vertex, and columnar properties use 4–8 bytes per vertex per column. String properties are dictionary-encoded, and null bitmaps cost just 1 bit per vertex per column.

In practice, enabling Graph OLAP adds a fraction of the memory your OLTP data already uses.

70 Built-in Graph Algorithms — All OLAP-Optimized

All 70 graph algorithms ship fully optimized for the Graph OLAP Engine, operating directly on CSR arrays with zero GC pressure and multi-threaded execution. When a GAV is available, every algorithm automatically uses the OLAP path — no configuration needed.

Category Algorithms
Path Finding Shortest Path, A*, Bellman-Ford, Dijkstra, Dijkstra Single Source, Duan SSSP, All Pairs Shortest Path (APSP), All Simple Paths, K Shortest Paths, Longest Path DAG, Steiner Tree
Traversal BFS, DFS
Centrality Degree, Closeness, Betweenness, Eigenvector, Harmonic, Eccentricity, HITS, Katz, ArticleRank
Ranking PageRank, Personalized PageRank, VoteRank
Community Detection Label Propagation, Louvain, Leiden, Strongly Connected Components (SCC), Weakly Connected Components (WCC), Biconnected Components, SLPA
Link Prediction Adamic-Adar, Common Neighbors, Jaccard Similarity, Preferential Attachment, Resource Allocation, SimRank
Clustering & Partitioning Local Clustering Coefficient, Triangle Count, Hierarchical Clustering, K-Means, Graph Coloring, Bipartite Check, Bipartite Matching
Subgraph Analysis Clique, K-Core, K-Truss, Densest Subgraph, Articulation Points, Bridges
Spanning Trees Minimum Spanning Tree (MST), Min Spanning Arborescence
Network Flow Max Flow, Max K-Cut
Graph Metrics Assortativity, Conductance, Modularity Score, Rich Club, Graph Summary, Total Neighbors, Same Community
ML & Embeddings Random Walk, Node2Vec, FastRP, GraphSAGE, HashGNN, Influence Maximization
Other Cycle Detection, Topological Sort

Getting Started

SQL

-- Create a view over your social graph
CREATE GRAPH ANALYTICAL VIEW social
  VERTEX TYPES (Person, Company)
  EDGE TYPES (FOLLOWS, WORKS_AT)
  PROPERTIES (name, age, status)
  UPDATE MODE SYNCHRONOUS

-- That's it. Your Cypher queries are now accelerated automatically.
-- You can also use edge properties for weighted algorithms:
CREATE GRAPH ANALYTICAL VIEW weighted
  VERTEX TYPES (City)
  EDGE TYPES (ROAD)
  EDGE PROPERTIES (distance, toll)
  UPDATE MODE SYNCHRONOUS

Java API

GraphAnalyticalView gav = GraphAnalyticalView.builder(database)
    .withName("social")
    .withVertexTypes("Person", "Company")
    .withEdgeTypes("FOLLOWS", "WORKS_AT")
    .withProperties("name", "age", "status")
    .withUpdateMode(UpdateMode.SYNCHRONOUS)
    .build();

// Run algorithms directly on the OLAP engine
GraphAlgorithms algos = new GraphAlgorithms();
double[] ranks = algos.pageRank(gav, 20, 0.85);
int[] components = algos.connectedComponents(gav);

Managing Views

-- Change update mode on the fly
ALTER GRAPH ANALYTICAL VIEW social UPDATE MODE ASYNCHRONOUS

-- Force a rebuild
REBUILD GRAPH ANALYTICAL VIEW social

-- Drop when no longer needed
DROP GRAPH ANALYTICAL VIEW social

Named views are persisted in the schema and automatically restored on database restart.

The Zero-Compromise Philosophy

Most databases force you to choose: fast transactions or fast analytics. Export your data to a separate system, maintain two clusters, deal with synchronization lag.

ArcadeDB’s Graph OLAP Engine rejects that tradeoff entirely:

  • Your OLTP engine stays exactly as it is — same speed, same ACID guarantees, same API
  • Turn on a GAV, and analytical queries get up to 462x faster automatically
  • Synchronization is configurable — real-time, async, or manual, your choice
  • Memory overhead is minimal — the OLAP representation is 9.0x more compact than OLTP
  • No query changes — the optimizer handles everything transparently

We were already the fastest OLTP graph database. Now we’re the fastest OLAP graph database too.


The Graph OLAP Engine is available from ArcadeDB v26.3.2. For detailed documentation, visit docs.arcadedb.com.

Try ArcadeDB: GitHub Docker Hub Documentation