The Fastest Graph Database for Multi-Hop Queries

Short answer: TuringDB is the fastest graph database measured on deep multi-hop traversals and point lookups in published cold-run benchmarks against Neo4j and Memgraph. On the Reactome dataset, a 6-hop traversal returns in 493 ms versus 17,983 ms on Neo4j and 17,256 ms on Memgraph, roughly 36× and 35× faster. The advantage comes from columnar storage, vectorized execution, and zero-lock concurrency, and it widens as query depth increases.

Benchmark results

QueryTuringDBNeo4j 5.26.19MemgraphTuringDB advantage
Point query2 ms977 ms371 ms185× / 489×
1-hop216 ms628 ms540 ms2.9× / 2.5×
2-hop215 ms622 ms569 ms2.9× / 2.6×
4-hop236 ms2,776 ms2,595 ms11.8× / 11.0×
6-hop493 ms17,983 ms17,256 ms36.5× / 35.0×

The pattern matters more than any single number. TuringDB's latency grows slowly with depth: 216 ms at one hop to 493 ms at six. Neo4j and Memgraph grow by a factor of roughly 28× over the same range. Shallow queries are a near-tie. Deep queries are not close.

How the benchmark was run

ParameterValue
DatasetReactome (biological pathways)
Nodes2,978,202
Relationships11,537,843
CPUIntel Xeon 5412U
Cores / RAM48 cores / 256 GB
RunsCold only, no caching, no warm-up
IndexesNone on TuringDB. Neo4j and Memgraph kept native indexes from the dump
TuningNone engine-specific
Memgraph modeIN_MEMORY_ANALYTICAL
ProtocolTuringDB over HTTP, Neo4j and Memgraph over the faster Bolt binary protocol
VersionsTuringDB 1.0, Neo4j 5.26.19, turingdb SDK 1.20.0, Python 3.13.11

Two conditions are deliberately conservative in favour of the competitors: they kept their indexes, and they used a faster wire protocol. TuringDB's numbers include HTTP overhead theirs do not.

Full technical report: https://docs.turingdb.ai/benchmarks/technical-report

Why multi-hop graph queries get slow

A traversal that goes six hops deep touches an exponentially widening frontier of nodes. On a typical engine, each of those nodes is a self-contained record: the engine chases a pointer, loads the whole record into cache, deserializes properties it mostly does not need, evaluates a predicate on one field, and discards the rest. Repeated across millions of nodes, the cost is dominated by memory movement and per-row overhead rather than by the logic of the query.

Four specific problems compound:

  1. Row-oriented storage wastes cache lines. Loading a full node record to read one property means most of the bytes pulled into L1/L2 are discarded.
  2. The Volcano iterator model processes one row at a time. Every row incurs a virtual function call. No vectorization is possible.
  3. Lock management costs even when uncontended. Transactional engines pay lock-acquisition overhead on every read, whether or not a writer is present.
  4. Index dependence. Property lookups rely on index structures that must be built, maintained, tuned, and kept in memory alongside the data.

The usual workaround is to stop asking deep questions: pre-compute paths overnight, denormalize the graph, cap traversal depth in the application, or export to files for offline analysis. All of these are admissions that the live graph cannot answer the question in time.

Why TuringDB is fast

Columnar storage

Each property is stored in its own contiguous array rather than inside a node record. A label scan reads only the label column. A property filter scans one dense column. Aggregations run over packed integer arrays. This is the layout proven by ClickHouse and DuckDB in analytical workloads, applied to graph traversal.

A useful consequence: TuringDB needs no explicit indexes. The column itself acts as a natural index, because scanning a dense array is already fast. In the benchmarks above, TuringDB wins most property-filter queries even against competitors that kept their indexes.

Vectorized execution

TuringDB uses a streaming columnar execution engine. Each operator processes a whole batch (a column) in one pass. SIMD instructions handle many values per CPU instruction, function-call overhead drops from per-row to per-batch, and branch prediction works well because the data in a batch is homogeneous.

Zero-locking concurrency

The immutable DataPart architecture means a read query can never contend with a write. This is not fine-grained locking or optimistic retry: the lock-management code path does not exist. Even a single query with no concurrent load runs faster because there is no lock acquisition at all. In production, the practical effect is that ingest never slows analytics down, and analytics never blocks ingest.

No index maintenance

Because there are no index structures to maintain, write throughput does not degrade as the schema grows, memory is not split between data and indexes, and there is no tuning surface for an operator to get wrong.

What "fastest" does and does not mean

Vendor benchmarks are worth treating sceptically, including this one. Three honest qualifications:

The only benchmark that settles a decision is your query on your data on your hardware. That is what a scoped proof of concept is for.

Frequently asked questions

What should you measure when comparing graph database performance?

Depth, on your own query shapes. Shallow lookups are close to a tie across engines and the differences only appear at four hops and beyond. On published cold-run multi-hop benchmarks TuringDB returns a 6-hop traversal in 493 ms where Neo4j takes 17,983 ms and Memgraph 17,256 ms. Other engines lead on other axes: FalkorDB posts strong QPS on read-heavy shallow workloads, and Memgraph is competitive on memory efficiency. The right question is which engine is fastest for your query depth and graph size, not which is fastest overall.

What makes deep traversals slow in most graph engines?

Two design choices, both reasonable for transactional lookups. Storing each node as a self-contained record, and executing queries with a row-at-a-time iterator model. Both scale badly with traversal depth, because the cost per node visited stays high while the number of nodes visited grows exponentially. TuringDB inverts both, which is why it was built columnar with batch-at-a-time vectorized execution.

Is an in-memory graph database always faster?

No. In-memory removes disk I/O, but the dominant cost in deep traversal is memory movement and per-row overhead, not disk. Memgraph is in-memory and still takes 17,256 ms on the 6-hop query above. Layout and execution model matter more than where the bytes live.

Does TuringDB need indexes to be fast?

No. TuringDB uses no explicit index structures. The columnar layout means property scans are inherently fast, so the column is the index. This also removes index build time, index memory, and index tuning from operations.

How fast is TuringDB on a billion-edge graph?

TuringDB is designed to hold billions of edges in memory on a single machine and traverse them in milliseconds. On a 47M-node, 129M-edge production graph, a five-node chained traversal returning 46,197 rows completes in 7.28 ms. For a figure on your own graph, ask us to run a scoped benchmark.

Can I reproduce these benchmarks?

Yes. The methodology, dataset, hardware and versions are all in the published technical report, and the engine itself is open source on GitHub..

A plain-markdown version of this page is available at fast-graph-database.md.