<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John David Paul</title>
    <description>The latest articles on DEV Community by John David Paul (@kalbashi09).</description>
    <link>https://dev.to/kalbashi09</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4096585%2F8158714e-c00d-419a-808b-c6eb9b6c0116.png</url>
      <title>DEV Community: John David Paul</title>
      <link>https://dev.to/kalbashi09</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kalbashi09"/>
    <language>en</language>
    <item>
      <title>Benchmarking 5 Graph Database Platforms on the Same 352k-Edge Graph: What Free Tiers Hide</title>
      <dc:creator>John David Paul</dc:creator>
      <pubDate>Thu, 27 Aug 2026 03:38:43 +0000</pubDate>
      <link>https://dev.to/kalbashi09/benchmarking-5-graph-database-platforms-on-the-same-352k-edge-graph-what-free-tiers-hide-39jm</link>
      <guid>https://dev.to/kalbashi09/benchmarking-5-graph-database-platforms-on-the-same-352k-edge-graph-what-free-tiers-hide-39jm</guid>
      <description>&lt;p&gt;Graph database benchmarks are easy to get wrong.&lt;/p&gt;

&lt;p&gt;Most public benchmarks compare expensive production instances, use different datasets, ignore network latency, hide free-tier throttling, or quietly optimize one database more than the others.&lt;/p&gt;

&lt;p&gt;For a recent engineering assignment from &lt;strong&gt;Wexa AI&lt;/strong&gt;, I decided to do the opposite.&lt;/p&gt;

&lt;p&gt;I built a small benchmark harness that compared &lt;strong&gt;CognoDB Cloud&lt;/strong&gt; against four other graph database platforms using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the same dataset&lt;/li&gt;
&lt;li&gt;the same logical queries&lt;/li&gt;
&lt;li&gt;the same client machine&lt;/li&gt;
&lt;li&gt;free or entry-level resource tiers&lt;/li&gt;
&lt;li&gt;warm-up before measurement&lt;/li&gt;
&lt;li&gt;percentile-based latency reporting&lt;/li&gt;
&lt;li&gt;automated one-command runs&lt;/li&gt;
&lt;li&gt;honest caveats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The platforms tested were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;CognoDB Cloud&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Neo4j Aura Free&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Neo4j Sandbox&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker-capped Neo4j Community&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memgraph Cloud&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The dataset was the SNAP &lt;code&gt;cit-HepTh&lt;/code&gt; citation network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;27,769 nodes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;352,768 relationships&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;papers citing other papers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small enough to fit inside free tiers, but large enough to make the benchmark meaningful.&lt;/p&gt;

&lt;p&gt;The full benchmark code, results, and documentation are available here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub repository:&lt;/strong&gt; [Add your GitHub repository link]&lt;/p&gt;




&lt;h2&gt;
  
  
  The Goal Was Not to Find a “Winner”
&lt;/h2&gt;

&lt;p&gt;The assignment was clear: the goal was not to crown a database.&lt;/p&gt;

&lt;p&gt;The goal was to evaluate engineering rigor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fair methodology&lt;/li&gt;
&lt;li&gt;reproducible automation&lt;/li&gt;
&lt;li&gt;honest reporting&lt;/li&gt;
&lt;li&gt;clear analysis&lt;/li&gt;
&lt;li&gt;documented caveats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters because real-world database selection is messy.&lt;/p&gt;

&lt;p&gt;There is no universal “best graph database.”&lt;/p&gt;

&lt;p&gt;There is only the best database for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your data size&lt;/li&gt;
&lt;li&gt;your query patterns&lt;/li&gt;
&lt;li&gt;your latency requirements&lt;/li&gt;
&lt;li&gt;your operational constraints&lt;/li&gt;
&lt;li&gt;your budget&lt;/li&gt;
&lt;li&gt;your deployment model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So this benchmark was designed to measure behavior under constrained free-tier conditions, not to simulate an unlimited production environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fairness Rules
&lt;/h2&gt;

&lt;p&gt;Before writing code, I set a few rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Same dataset everywhere
&lt;/h3&gt;

&lt;p&gt;Every platform received the exact same graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Same logical queries everywhere
&lt;/h3&gt;

&lt;p&gt;All platforms ran the same workloads, even where minor Cypher dialect adjustments were required.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Free or entry tiers only
&lt;/h3&gt;

&lt;p&gt;No paid production instance was allowed to sneak into the comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Small resource footprint
&lt;/h3&gt;

&lt;p&gt;CognoDB’s free tier is intentionally small:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;burstable 0.5 vCPU&lt;/li&gt;
&lt;li&gt;256 MB RAM&lt;/li&gt;
&lt;li&gt;1 GB disk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the other platforms were run on their free, trial, or capped self-hosted tiers.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Warm-up before measurement
&lt;/h3&gt;

&lt;p&gt;Every read workload was warmed up first. Cold-start behavior was excluded from the main latency numbers and documented as a caveat.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Percentiles, not just averages
&lt;/h3&gt;

&lt;p&gt;Averages can hide bad requests.&lt;/p&gt;

&lt;p&gt;So the benchmark reported:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;p50 latency: typical behavior&lt;/li&gt;
&lt;li&gt;p95 latency: tail behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. No hidden caveats
&lt;/h3&gt;

&lt;p&gt;If something failed, throttled, crashed, or behaved strangely, it got documented.&lt;/p&gt;

&lt;p&gt;That rule ended up being one of the most valuable parts of the project.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Dataset
&lt;/h2&gt;

&lt;p&gt;I used the SNAP &lt;code&gt;cit-HepTh&lt;/code&gt; citation network.&lt;/p&gt;

&lt;p&gt;It represents arXiv High Energy Physics Theory papers and their citations.&lt;/p&gt;

&lt;p&gt;If paper A cites paper B, the graph contains a directed edge from A to B.&lt;/p&gt;

&lt;p&gt;The final cleaned graph contained:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nodes&lt;/td&gt;
&lt;td&gt;27,769&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relationships&lt;/td&gt;
&lt;td&gt;352,768&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node label&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Paper&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relationship type&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CITES&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each paper node had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;year&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;field&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;year&lt;/code&gt; property came from the original SNAP metadata.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;field&lt;/code&gt; property was generated deterministically for aggregation testing, so every platform received identical values.&lt;/p&gt;

&lt;p&gt;This dataset was a good fit because it had enough relationships to make traversals and aggregations interesting, but it was still small enough to fit into free tiers.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Benchmark Harness
&lt;/h2&gt;

&lt;p&gt;I built the benchmark harness in C# using .NET 8 and the official Neo4j .NET driver.&lt;/p&gt;

&lt;p&gt;For each platform, the harness did the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;downloaded and prepared the dataset if needed&lt;/li&gt;
&lt;li&gt;connected using secrets from environment variables&lt;/li&gt;
&lt;li&gt;wiped old benchmark data&lt;/li&gt;
&lt;li&gt;created indexes and constraints&lt;/li&gt;
&lt;li&gt;loaded nodes and relationships in batches&lt;/li&gt;
&lt;li&gt;ran warm-up queries&lt;/li&gt;
&lt;li&gt;measured read workloads over 100 iterations&lt;/li&gt;
&lt;li&gt;reported p50 and p95 latency&lt;/li&gt;
&lt;li&gt;ran mixed read/write workloads at 1, 10, and 40 concurrent clients&lt;/li&gt;
&lt;li&gt;saved results as JSON&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then a report generator converted the JSON files into Markdown tables.&lt;/p&gt;

&lt;p&gt;The workflow was simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet run &lt;span class="nt"&gt;--&lt;/span&gt; cognodb
dotnet run &lt;span class="nt"&gt;--&lt;/span&gt; aura
dotnet run &lt;span class="nt"&gt;--&lt;/span&gt; sandbox
dotnet run &lt;span class="nt"&gt;--&lt;/span&gt; memgraph
dotnet run &lt;span class="nt"&gt;--&lt;/span&gt; docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet run &lt;span class="nt"&gt;--&lt;/span&gt; report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No passwords were stored in the repository. All credentials were read from environment variables.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Workloads
&lt;/h2&gt;

&lt;p&gt;The benchmark measured six categories.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Ingest throughput
&lt;/h3&gt;

&lt;p&gt;How fast can the platform load the graph?&lt;/p&gt;

&lt;p&gt;Measured as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nodes per second&lt;/li&gt;
&lt;li&gt;relationships per second&lt;/li&gt;
&lt;li&gt;total wall-clock load time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Traversals
&lt;/h3&gt;

&lt;p&gt;One-hop, two-hop, and three-hop queries from randomly selected start nodes.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Paper&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;$id&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:CITES&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:CITES&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Lookups
&lt;/h3&gt;

&lt;p&gt;Point lookup by indexed &lt;code&gt;id&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Paper&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;$id&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.year&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Filtered lookup using indexed &lt;code&gt;year&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Paper&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;p.year&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;$y1&lt;/span&gt; &lt;span class="ow"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;p.year&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;$y2&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Aggregation
&lt;/h3&gt;

&lt;p&gt;Group-by query over a node property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Paper&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.field&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Mixed read/write workload
&lt;/h3&gt;

&lt;p&gt;The mixed workload used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;80% reads&lt;/li&gt;
&lt;li&gt;20% writes&lt;/li&gt;
&lt;li&gt;1, 10, and 40 concurrent clients&lt;/li&gt;
&lt;li&gt;30 seconds per concurrency level&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Footprint
&lt;/h3&gt;

&lt;p&gt;Where observable, the benchmark recorded:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;node count&lt;/li&gt;
&lt;li&gt;relationship count&lt;/li&gt;
&lt;li&gt;resource limits&lt;/li&gt;
&lt;li&gt;available platform metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where a platform did not expose internals, the result was marked as &lt;strong&gt;not observable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results: Ingest Throughput
&lt;/h2&gt;

&lt;p&gt;Memgraph dominated ingest.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Relationships/sec&lt;/th&gt;
&lt;th&gt;Total Load Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memgraph&lt;/td&gt;
&lt;td&gt;14,966&lt;/td&gt;
&lt;td&gt;25.7s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker Neo4j&lt;/td&gt;
&lt;td&gt;8,144&lt;/td&gt;
&lt;td&gt;55.2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Aura&lt;/td&gt;
&lt;td&gt;7,865&lt;/td&gt;
&lt;td&gt;47.6s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Sandbox&lt;/td&gt;
&lt;td&gt;2,339&lt;/td&gt;
&lt;td&gt;167.9s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CognoDB&lt;/td&gt;
&lt;td&gt;1,209&lt;/td&gt;
&lt;td&gt;317.9s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Visual summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;memgraph   14966 rels/sec  ████████████████████████████████
docker      8144 rels/sec  █████████████████
aura        7865 rels/sec  ████████████████
sandbox     2339 rels/sec  █████
cognodb     1209 rels/sec  ██
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Memgraph’s in-memory architecture gave it a major advantage during batched loading.&lt;/p&gt;

&lt;p&gt;Aura also performed strongly.&lt;/p&gt;

&lt;p&gt;Docker Neo4j benefited from local execution and no cloud network overhead.&lt;/p&gt;

&lt;p&gt;CognoDB and Sandbox were slower under the tested free-tier conditions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results: Traversal Latency
&lt;/h2&gt;

&lt;p&gt;For traversal latency, Docker Neo4j had the lowest p50 numbers because it ran locally.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;1-hop p50&lt;/th&gt;
&lt;th&gt;2-hop p50&lt;/th&gt;
&lt;th&gt;3-hop p50&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker Neo4j&lt;/td&gt;
&lt;td&gt;3.1 ms&lt;/td&gt;
&lt;td&gt;3.2 ms&lt;/td&gt;
&lt;td&gt;3.3 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memgraph&lt;/td&gt;
&lt;td&gt;95.3 ms&lt;/td&gt;
&lt;td&gt;95.8 ms&lt;/td&gt;
&lt;td&gt;96.2 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Aura&lt;/td&gt;
&lt;td&gt;146.2 ms&lt;/td&gt;
&lt;td&gt;146.5 ms&lt;/td&gt;
&lt;td&gt;146.8 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CognoDB&lt;/td&gt;
&lt;td&gt;644.2 ms&lt;/td&gt;
&lt;td&gt;652.3 ms&lt;/td&gt;
&lt;td&gt;654.2 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Sandbox&lt;/td&gt;
&lt;td&gt;697.8 ms&lt;/td&gt;
&lt;td&gt;697.7 ms&lt;/td&gt;
&lt;td&gt;698.0 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One pattern stood out.&lt;/p&gt;

&lt;p&gt;For most platforms, latency barely increased from one hop to three hops.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aura: 146.2 ms to 146.8 ms&lt;/li&gt;
&lt;li&gt;Memgraph: 95.3 ms to 96.2 ms&lt;/li&gt;
&lt;li&gt;Sandbox: 697.8 ms to 698.0 ms&lt;/li&gt;
&lt;li&gt;CognoDB: 644.2 ms to 654.2 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That tells us something important.&lt;/p&gt;

&lt;p&gt;At this dataset size, the actual traversal work was small compared with fixed overhead.&lt;/p&gt;

&lt;p&gt;That overhead may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;network round-trip time&lt;/li&gt;
&lt;li&gt;request parsing&lt;/li&gt;
&lt;li&gt;query planning&lt;/li&gt;
&lt;li&gt;serialization&lt;/li&gt;
&lt;li&gt;connection handling&lt;/li&gt;
&lt;li&gt;free-tier CPU scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, the query engine may not have been the dominant cost. The request path was.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results: Lookups and Aggregations
&lt;/h2&gt;

&lt;p&gt;Lookup latency followed a similar pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Point lookup p50
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Point Lookup p50&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker Neo4j&lt;/td&gt;
&lt;td&gt;3.3 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memgraph&lt;/td&gt;
&lt;td&gt;95.1 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Aura&lt;/td&gt;
&lt;td&gt;146.1 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CognoDB&lt;/td&gt;
&lt;td&gt;643.9 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Sandbox&lt;/td&gt;
&lt;td&gt;698.8 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Aggregation p50
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Aggregation p50&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker Neo4j&lt;/td&gt;
&lt;td&gt;13.9 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memgraph&lt;/td&gt;
&lt;td&gt;106.0 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Aura&lt;/td&gt;
&lt;td&gt;156.8 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CognoDB&lt;/td&gt;
&lt;td&gt;683.7 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Sandbox&lt;/td&gt;
&lt;td&gt;704.6 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Docker’s low numbers again reflected its localhost advantage.&lt;/p&gt;

&lt;p&gt;Among cloud platforms, Memgraph and Aura were the strongest in this test.&lt;/p&gt;

&lt;p&gt;CognoDB remained stable, but its latency was dominated by what appeared to be fixed request overhead under the tested free-tier environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results: Mixed Read/Write Workload
&lt;/h2&gt;

&lt;p&gt;The mixed workload used 80% reads and 20% writes.&lt;/p&gt;

&lt;p&gt;At 40 concurrent clients:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;QPS&lt;/th&gt;
&lt;th&gt;Errors&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker Neo4j&lt;/td&gt;
&lt;td&gt;378.4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memgraph&lt;/td&gt;
&lt;td&gt;374.4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Aura&lt;/td&gt;
&lt;td&gt;287.7&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CognoDB&lt;/td&gt;
&lt;td&gt;61.2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Neo4j Sandbox&lt;/td&gt;
&lt;td&gt;51.3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Visual summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker     378.4 QPS  ████████████████████████████████
memgraph   374.4 QPS  ███████████████████████████████
aura       287.7 QPS  ████████████████████████
cognodb     61.2 QPS  █████
sandbox     51.3 QPS  ████
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker and Memgraph achieved the highest throughput.&lt;/p&gt;

&lt;p&gt;Aura scaled well and completed the workload with no recorded errors.&lt;/p&gt;

&lt;p&gt;CognoDB and Sandbox showed lower absolute throughput, but both completed with zero recorded errors.&lt;/p&gt;

&lt;p&gt;Memgraph produced five errors during the 40-client workload. I kept those errors in the results because hiding them would defeat the purpose of an honest benchmark. The likely explanation is resource pressure on the entry-tier instance under concurrent writes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Surprise #1: Java Does Not Like Strict 256 MB Containers
&lt;/h2&gt;

&lt;p&gt;One of the most interesting findings came from Docker Neo4j.&lt;/p&gt;

&lt;p&gt;CognoDB’s free tier gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0.5 vCPU&lt;/li&gt;
&lt;li&gt;256 MB RAM&lt;/li&gt;
&lt;li&gt;1 GB disk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted the local Docker Neo4j instance to be as close to that as possible.&lt;/p&gt;

&lt;p&gt;So I first capped the Docker container at 256 MB.&lt;/p&gt;

&lt;p&gt;Neo4j crashed during startup.&lt;/p&gt;

&lt;p&gt;It did not fail during the benchmark. It failed before it could serve queries.&lt;/p&gt;

&lt;p&gt;The fix was to distinguish between two different memory concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;container memory ceiling&lt;/li&gt;
&lt;li&gt;database JVM heap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final Docker configuration used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;512 MB container ceiling&lt;/li&gt;
&lt;li&gt;256 MB Neo4j JVM heap max&lt;/li&gt;
&lt;li&gt;50 MB Neo4j page cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That distinction mattered.&lt;/p&gt;

&lt;p&gt;The database heap was still limited to 256 MB, but the JVM needed additional headroom just to run.&lt;/p&gt;

&lt;p&gt;This became one of my favorite architectural observations from the project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A database memory limit is not always the same thing as a process memory limit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It also highlighted a difference between lightweight engines and JVM-based engines. CognoDB’s free tier operates within a very small total footprint, while Java-based Neo4j requires more baseline headroom.&lt;/p&gt;




&lt;h2&gt;
  
  
  Surprise #2: Free-Tier Latency Is Often About Fixed Overhead
&lt;/h2&gt;

&lt;p&gt;The traversal results were interesting because latency barely changed as query complexity increased.&lt;/p&gt;

&lt;p&gt;If the graph traversal itself were the dominant cost, we would expect three-hop queries to be noticeably slower than one-hop queries.&lt;/p&gt;

&lt;p&gt;But for several platforms, they were almost identical.&lt;/p&gt;

&lt;p&gt;That suggests that the measured latency was dominated by fixed overhead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;network round-trip time&lt;/li&gt;
&lt;li&gt;request handling&lt;/li&gt;
&lt;li&gt;query planning&lt;/li&gt;
&lt;li&gt;serialization&lt;/li&gt;
&lt;li&gt;scheduling&lt;/li&gt;
&lt;li&gt;free-tier throttling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is an important lesson for anyone reading database benchmarks.&lt;/p&gt;

&lt;p&gt;A slow result does not always mean the engine is slow.&lt;/p&gt;

&lt;p&gt;It may mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the instance is tiny&lt;/li&gt;
&lt;li&gt;the network path is distant&lt;/li&gt;
&lt;li&gt;the CPU is burstable&lt;/li&gt;
&lt;li&gt;the environment is shared&lt;/li&gt;
&lt;li&gt;the platform is throttling free-tier traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Honest benchmarks need to say that clearly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Surprise #3: Docker Is Useful, but It Is Not a Fair Cloud Comparison
&lt;/h2&gt;

&lt;p&gt;Docker Neo4j had the lowest latency in almost every category.&lt;/p&gt;

&lt;p&gt;But that result must be interpreted carefully.&lt;/p&gt;

&lt;p&gt;Docker ran on the same machine as the benchmark client.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no internet round-trip time&lt;/li&gt;
&lt;li&gt;no cloud routing&lt;/li&gt;
&lt;li&gt;no managed-service request overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker results are useful as a local engine baseline, but they are not directly comparable to cloud platforms over a network.&lt;/p&gt;

&lt;p&gt;This is one of the reasons I included Docker in the first place.&lt;/p&gt;

&lt;p&gt;It helped separate two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How does the engine behave locally?&lt;/li&gt;
&lt;li&gt;How does the managed platform behave over a real network path?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those are related, but they are not the same.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Importance of Percentiles
&lt;/h2&gt;

&lt;p&gt;One of the requirements I’m glad the assignment enforced was percentile reporting.&lt;/p&gt;

&lt;p&gt;Docker Neo4j had very low p50 latency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;around 3 ms for lookups&lt;/li&gt;
&lt;li&gt;around 14 ms for aggregation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But its p95 latency jumped to around 80 ms in several workloads.&lt;/p&gt;

&lt;p&gt;That gap matters.&lt;/p&gt;

&lt;p&gt;Averages could make Docker look almost perfect. But p95 revealed occasional pauses, likely related to JVM behavior, caching, or local scheduling.&lt;/p&gt;

&lt;p&gt;In production, users often notice the tail more than the average.&lt;/p&gt;

&lt;p&gt;A system that usually responds in 5 ms but occasionally responds in 100 ms can feel worse than a system that consistently responds in 30 ms.&lt;/p&gt;

&lt;p&gt;Percentiles expose that.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Results Suggest
&lt;/h2&gt;

&lt;p&gt;Under the conditions of this benchmark:&lt;/p&gt;

&lt;h3&gt;
  
  
  Memgraph
&lt;/h3&gt;

&lt;p&gt;Memgraph showed strong ingest throughput and strong cloud latency. Its in-memory architecture appears to benefit both batch loading and read workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Neo4j Aura
&lt;/h3&gt;

&lt;p&gt;Aura showed strong managed-cloud behavior, especially considering it was running on a free tier. It scaled well under concurrency and completed mixed workloads with zero recorded errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Neo4j
&lt;/h3&gt;

&lt;p&gt;Docker Neo4j produced the lowest local latency, but its results include a localhost advantage and should not be treated as a direct cloud comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  Neo4j Sandbox
&lt;/h3&gt;

&lt;p&gt;Sandbox behaved like a managed trial environment with relatively high fixed request latency. It is useful for evaluation, but its internal resource guarantees are not publicly detailed.&lt;/p&gt;

&lt;h3&gt;
  
  
  CognoDB
&lt;/h3&gt;

&lt;p&gt;CognoDB completed all benchmark workloads with zero mixed-workload errors. Its free tier is intentionally small, and under the tested network path it showed higher request latency and lower throughput than some other platforms.&lt;/p&gt;

&lt;p&gt;The important caveat is that this reflects the free-tier conditions and client network path used in this test. It does not necessarily represent CognoDB’s behavior under larger instances, closer regions, or production configurations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest Caveats
&lt;/h2&gt;

&lt;p&gt;This benchmark has limitations, and they matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Free tiers are noisy
&lt;/h3&gt;

&lt;p&gt;Free instances may be shared, throttled, or burstable. Results can vary over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network path matters
&lt;/h3&gt;

&lt;p&gt;Cloud platforms were tested from a residential internet connection. Different regions or networks could produce different results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not all specs are public
&lt;/h3&gt;

&lt;p&gt;Some platforms do not expose exact vCPU, RAM, or storage details for free tiers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker has a localhost advantage
&lt;/h3&gt;

&lt;p&gt;Docker Neo4j avoids cloud network latency, so it should be interpreted as a local baseline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker needed more container memory than CognoDB
&lt;/h3&gt;

&lt;p&gt;Neo4j’s JVM required extra headroom beyond the 256 MB database heap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warm numbers only
&lt;/h3&gt;

&lt;p&gt;The reported latency numbers are warm-run numbers. Cold-start behavior was not separately benchmarked.&lt;/p&gt;

&lt;h3&gt;
  
  
  One full measurement pass
&lt;/h3&gt;

&lt;p&gt;Each read workload used 100 iterations, but the full suite was not repeated across multiple days due to the 48-hour assignment window.&lt;/p&gt;

&lt;h3&gt;
  
  
  Engine diversity
&lt;/h3&gt;

&lt;p&gt;Aura, Sandbox, and Docker all use Neo4j-based engines. They were included to compare different deployment models. Memgraph provided a different in-memory architecture. Future work could include additional distinct engines such as FalkorDB, ArangoDB, NebulaGraph, or TigerGraph.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Would Improve Next
&lt;/h2&gt;

&lt;p&gt;If I had more time, I would extend the benchmark in several ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add more distinct engines
&lt;/h3&gt;

&lt;p&gt;FalkorDB, ArangoDB, NebulaGraph, TigerGraph, and Kùzu would make the comparison more diverse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run repeated full-suite passes
&lt;/h3&gt;

&lt;p&gt;Multiple runs across different times would help measure variance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add cold-start benchmarking
&lt;/h3&gt;

&lt;p&gt;Cold-start latency is important for serverless and scale-to-zero environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Collect platform metrics
&lt;/h3&gt;

&lt;p&gt;Where available, I would collect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage&lt;/li&gt;
&lt;li&gt;memory usage&lt;/li&gt;
&lt;li&gt;disk usage&lt;/li&gt;
&lt;li&gt;request errors&lt;/li&gt;
&lt;li&gt;saturation metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generate charts automatically
&lt;/h3&gt;

&lt;p&gt;The current report uses Markdown tables and simple text charts. A chart generator would make the results easier to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test larger datasets
&lt;/h3&gt;

&lt;p&gt;The current dataset fits free tiers. A larger dataset would stress indexing, memory, and storage more aggressively.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Lesson
&lt;/h2&gt;

&lt;p&gt;The biggest lesson from this project was not “Database X is faster.”&lt;/p&gt;

&lt;p&gt;The bigger lesson was that benchmarking is a systems problem.&lt;/p&gt;

&lt;p&gt;You are not only measuring the database engine.&lt;/p&gt;

&lt;p&gt;You are measuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the network&lt;/li&gt;
&lt;li&gt;the driver&lt;/li&gt;
&lt;li&gt;the query language&lt;/li&gt;
&lt;li&gt;the instance size&lt;/li&gt;
&lt;li&gt;the storage engine&lt;/li&gt;
&lt;li&gt;the runtime&lt;/li&gt;
&lt;li&gt;the cloud tier&lt;/li&gt;
&lt;li&gt;the client machine&lt;/li&gt;
&lt;li&gt;the workload design&lt;/li&gt;
&lt;li&gt;the honesty of the methodology&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you ignore those things, your benchmark may be technically reproducible but practically misleading.&lt;/p&gt;

&lt;p&gt;If you document them, your benchmark becomes useful.&lt;/p&gt;

&lt;p&gt;That was the spirit of this assignment.&lt;/p&gt;

&lt;p&gt;Not to hide the messy parts.&lt;/p&gt;

&lt;p&gt;Not to smooth over the caveats.&lt;/p&gt;

&lt;p&gt;Not to declare a winner.&lt;/p&gt;

&lt;p&gt;But to measure carefully, explain clearly, and leave the next engineer enough information to reproduce the work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;The benchmark harness, results, and full documentation are available here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub repository:&lt;/strong&gt; &lt;a href="https://github.com/kalbashi09/Benchmark" rel="noopener noreferrer"&gt;https://github.com/kalbashi09/Benchmark&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The README includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;full results tables&lt;/li&gt;
&lt;li&gt;platform specs&lt;/li&gt;
&lt;li&gt;dataset details&lt;/li&gt;
&lt;li&gt;query workloads&lt;/li&gt;
&lt;li&gt;methodology&lt;/li&gt;
&lt;li&gt;caveats&lt;/li&gt;
&lt;li&gt;reproducibility instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are evaluating graph databases, I hope this helps you ask better questions before trusting any benchmark.&lt;/p&gt;

&lt;p&gt;Including mine.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>database</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
