131,072 hops deep: Semurg walks a social graph up to 1,099 times faster than the incumbents
18 October 2026 · Semurg · 4 min read · Markdown
benchmarksgraphtraversalneo4jarcadedbfalkordbsurrealdbperformance
How deep can a database follow relationships before it gives up? We took one person in a public social graph of 117.2 million relationships[14] and asked every engine for everyone it could reach at each depth, from 2 hops all the way to 131,072, checking every answer against two independent reference implementations. Inside your application, one walk to 131,072 hops took Semurg 96.88 ms, ArcadeDB's embedded mode 459.74 ms[5], FalkorDB (no in-process mode: its fastest connection) 412.67 ms[6] and Neo4j's embedded mode 15,757.31 ms[4]. SurrealDB's embedded mode needed 109,350.14 ms for a single walk to 256 hops, its deepest, where Semurg needed 99.54 ms[8].
The test
The same data, machine and engines as our 4-hop comparison: SNAP's com-Orkut social graph, 3.07 million people[14], on one bare-metal AMD EPYC server, every engine in Docker with every thread and the same data disk, each through its fastest connection. Every depth is its own query from the same person: 2, 4, 8 and every doubling after that up to 131,072 hops. Each engine runs the whole ladder cold, warm and warm again; the figures are the warm medians.
Why the time jumps by 8 hops and then stays flat
Semurg's own times show the shape every engine shares: 0.135 ms at 2 hops[1], 3.515 ms at 4 hops[2], 95.946 ms at 8 hops[3], and 96.884 ms at 131,072 hops[4].
The jump is the graph, not the engine. A social network is small: from one person, 4 hops already reach 455,604 people[14], and by 8 hops the walk has reached nearly everyone it ever will. From there every deeper query walks the same whole graph again, so the time per depth stops growing: a walk to 131,072 hops costs Semurg the same as a walk to 8. Every engine bends at the same place; Neo4j's embedded mode goes from 17.108 ms at 2 hops to 15,594.362 ms at 8[1][3].
Inside your application
At full depth Semurg is 4.7 times faster than ArcadeDB's embedded mode[5] and 163 times faster than Neo4j's embedded mode[4]. FalkorDB and FalkorDBLite have no in-process mode, so in this column each runs through its fastest connection, as on the benchmark page: Semurg is 4.3 times faster than FalkorDB[6] and 4.4 times faster than FalkorDBLite[7].
SurrealDB's embedded mode is in a class of its own: 103,220.11 ms for one walk to 8 hops against Semurg's 95.95 ms[9], and 109,350.14 ms at 256 hops against 99.54 ms[8], which is 1,099 times slower. It did not go deeper in this run.
As a server
Through each engine's own server connection, one walk to 131,072 hops took Semurg 95.22 ms, ArcadeDB 113.71 ms[10], FalkorDB 412.67 ms[11] and Neo4j 14,033.83 ms[12].
ArcadeDB's server is the closest anyone comes: Semurg is ahead at the deepest depth[10], and at 8 hops the two are published as level[13]. That is the gap we are closing next.
Faster every release
Semurg ships continuously. Before any release is published it must pass a performance gate on the core operations (writing, reading, traversing and scanning), and a release that would make them slower does not ship. This ladder is re-run as the engine improves, and each re-run replaces the figures here and on the benchmark page.
Deeper, and bigger than memory
This graph fits in memory. The next ladder runs on a social graph many times larger than the memory each engine is given, at the same extreme depths, where a database has to keep walking while most of the graph sits on disk. Its results go on the benchmark page and into a post of their own when the run finishes.
Run it yourself
The kit behind every figure here is published; one command runs the whole graph comparison, this ladder included, on a Linux machine with Docker: curl -fsSL https://one.semurg.io/bench | sudo bash -s -- --graph. Read the script first with curl -fsSL https://one.semurg.io/bench | less. Every depth for every engine, in both columns, is in the ladder tables on the benchmark page.
Evidence
- Benchmark Walk from 2 to 131,072 hops: 2 hops: Semurg 0.135, neo4j 17.108 (r11.108) (bench:graph/t4_h2/embedded/neo4j@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 4 hops: Semurg 3.515, neo4j 653.257 (r11.108) (bench:graph/t4_h4/embedded/neo4j@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 8 hops: Semurg 95.946, neo4j 15594.362 (r11.108) (bench:graph/t4_h8/embedded/neo4j@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 96.884, neo4j 15757.31 (r11.108) (bench:graph/t4_h131072/embedded/neo4j@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 96.884, arcadedb 459.735 (r11.108) (bench:graph/t4_h131072/embedded/arcadedb@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 96.884, falkordb 412.67 (r11.108) (bench:graph/t4_h131072/embedded/falkordb@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 96.884, falkordblite 430.788 (r11.108) (bench:graph/t4_h131072/embedded/falkordblite@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 256 hops: Semurg 99.54, surrealdb 109350.14 (r11.108) (bench:graph/t4_h256/embedded/surrealdb@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 8 hops: Semurg 95.946, surrealdb 103220.106 (r11.108) (bench:graph/t4_h8/embedded/surrealdb@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 95.22, arcadedb 113.71 (r11.108) (bench:graph/t4_h131072/server/arcadedb@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 95.22, falkordb 412.67 (r11.108) (bench:graph/t4_h131072/server/falkordb@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 131072 hops: Semurg 95.22, neo4j 14033.828 (r11.108) (bench:graph/t4_h131072/server/neo4j@r11.108; the record as JSON)
- Benchmark Walk from 2 to 131,072 hops: 8 hops: Semurg 108.554, arcadedb 113.489 (r11.108) (bench:graph/t4_h8/server/arcadedb@r11.108; the record as JSON)
- Benchmark One query, 4 hops: Semurg 3.83, arcadedb 73.14 (r11.108) (bench:graph/t2/server/arcadedb@r11.108; the record as JSON)