Wir haben Neo4j, FalkorDB und Memgraph anhand eines synthetischen Graphen, der aus 120.000 Amazon-Produktrezensionen (381.000 Knoten, 804.000 Kanten) abgeleitet wurde, getestet. Wir führten zwölf Abfragevorlagen mit jeweils 1.000 Messungen durch, prüften die Datenaufnahme mit sechs verschiedenen Batchgrößen, die gleichzeitige Last über 60 Sekunden mit bis zu 32 Threads und maßen den Speicherverbrauch, den Kaltstart, die Auswirkungen auf gemischte Arbeitslasten und den Index.
FalkorDB erzielte bei 8 Threads einen höheren Durchsatz als Neo4j und Memgraph.
Ergebnisse des Graphdatenbank-Benchmarks
Gleichzeitiger Durchsatz
QPS (Abfragen pro Sekunde) misst, wie viele Leseanfragen die Datenbank pro Sekunde unter anhaltender Multithread-Last beantwortet. Jeder Durchlauf dauert 60 Sekunden. Je höher der Wert, desto besser.
Abfragelatenz (p50)
p50 ist die mittlere Latenz: Die Hälfte aller Anfragen wird schneller abgeschlossen als dieser Wert. Je niedriger, desto besser.
- Punktbasierte Suche: Abrufen eines einzelnen Knotens anhand seiner ID. Die Redis-Hashtabellen von FalkorDB führen In-Memory-Suchen in O(1) durch und sind damit etwa dreimal schneller.
- Traversierung: Vom Knoten zu seinen Nachbarn (1-Hop) oder zu Nachbarn von Nachbarn (2-Hop). FalkorDB ist bei 2-Hop-Traversierungen 2,9-mal schneller.
- Aggregation: Zähle die Bewertungen pro Marke und berechne die durchschnittliche Sternebewertung.
- Filtern + Scannen: Filtert Rezensionen nach Sternebewertung im gesamten Datensatz.
Aufnahmedurchsatz
Der Datendurchsatz misst, wie viele Rezensionen pro Sekunde die Datenbank schreiben kann. Jeder Punkt im Diagramm repräsentiert eine andere Batchgröße: wie viele Rezensionen in einer einzigen Abfrage zusammengefasst werden. Je höher der Wert, desto besser.
Bei einer Batchgröße von 1 ist Memgraph führend (1.427/s). Mit zunehmender Batchgröße skaliert FalkorDB steil und überholt Memgraph ab etwa Batchgröße 500. Neo4j erreicht unabhängig von der Batchgröße ein Plateau bei ca. 10.600/s. Bei Batchgröße 5.000 erreicht FalkorDB 22.784/s, das 77-Fache seiner Leistung bei Batchgröße 1.
Sie können mehr über unsere Benchmark-Methodik für Graphdatenbanken lesen.
Wichtigste Erkenntnisse
FalkorDB erreicht 6.693 QPS bei 8 Threads, 6.7x Neo4j
Die In-Memory-Datenstrukturen und die Ereignisschleife von Redis ermöglichen die Kombination von Abfragen mit geringer Latenz und hoher Parallelität. Ab acht Threads stagniert der Durchsatz, da die Kapazität des Single-Thread-Kerns von Redis begrenzt ist. Neo4j erreicht einen Spitzenwert von 16 Threads (1.010 QPS) und fällt dann bei 32 Threads (927 QPS) ab, was auf Thread-Konflikte hindeutet.
FalkorDB startet kalt in 1,1 ms, 82-mal schneller als Neo4j.
Neo4j benötigt nach einem Neustart 90 ms, um die erste Anfrage zu verarbeiten. Die erste Abfrage zum Aufwärmen dauert 274 ms, danach benötigt man etwa drei weitere Anfragen, um die Antwortzeit auf 34 ms einzupendeln. FalkorDB ist in 1,1 ms bereit, die erste Anfrage dauert nur 0,4 ms. In einer Microservice- oder Serverless-Umgebung, in der die Anzahl der Pods flexibel skaliert wird, ist diese Verzögerung relevant.
Indizes: 1.700-facher Unterschied bei Neo4j, ~1-facher Unterschied bei FalkorDB
Ohne Indizes benötigte die Neo4j-Abfrage deep_feature_products 293 ms. Mit Indizes waren es nur 0,17 ms. Das entspricht einem Unterschied um den Faktor 1.712. Memgraph zeigte eine ähnliche Sensitivität (160- bis 898-fach, abhängig von der Abfrage). Die Ergebnisse von FalkorDB blieben mit und ohne Indizes nahezu unverändert, da Redis-Hashtabellen bereits als implizite Indizes fungieren.
Speicher: 415 MB vs. 2.668 MB für dasselbe Diagramm
- Memgraph: 415 MB
- FalkorDB: 496 MB
- Neo4j: 2.668 MB (JMX-Heap verwendet)
Die JVM von Neo4j reserviert beim Start 4 GB Speicher, sodass der Prozessspeicher (VmRSS) unabhängig von der tatsächlichen Datennutzung immer etwa 5,2 GB beträgt. Die JMX-Heap-Metrik ist aussagekräftig. Der Spitzenwert von 2,7 GB sollte für die Kapazitätsplanung verwendet werden.
Neo4j gewann die schwerste Aggregation.
FalkorDB wies bei 11 von 12 Abfragen die niedrigste Latenz auf. Die Ausnahme bildete die Abfrage agg_feature_sentiment (Gruppierung nach Sentiment mit Filterung), bei der der Abfrageoptimierer von Neo4j einen besseren Ausführungsplan lieferte: 131 ms gegenüber 152 ms bei FalkorDB.
Gemischte Arbeitslast (80 % Lesen, 20 % Schreiben)
8 Threads, 60 Sekunden, null Fehler über alle drei Datenbanken hinweg:
- FalkorDB: 50.223 Operationen (837 Anfragen pro Sekunde)
- Neo4j: 44.256 Operationen (738 Abfragen pro Sekunde)
- Memgraph: 28.040 Operationen (467 QPS)
Schreibvorgänge beeinträchtigten die Leseleistung bei keinem der Geräte merklich.
Architekturen in diesem Benchmark
Jede Datenbank verfügt über eine eigene Verwaltungsoberfläche. Diese Screenshots zeigen denselben Datensatz (16.127 Knoten, 24.318 Kanten), der in alle drei Datenbanken geladen wurde und dieselbe COMPARED_WITH-Abfrage ausführt.
FalkorDB
FalkorDB ist ein Graphmodul, das auf dem In-Memory-Key-Value-Speicher von Redis basiert. Die Abfragen erfolgen mit OpenCypher, basieren aber im Kern auf Redis-Hashtabellen. Daher liegen die Antwortzeiten für Punktabfragen zwischen 0,044 und 0,048 ms.
Die beiden anderen Datenbanken in diesem Benchmark erzielten bei denselben Abfragen 2- bis 3-mal höhere Werte. Der Nachteil besteht darin, dass der Single-Thread-Kern von Redis dazu führt, dass der gleichzeitige Durchsatz ab 8 Threads nicht mehr skaliert.
Neo4j
Neo4j läuft auf der JVM. Die JIT-Kompilierung führt dazu, dass wiederholte Abfragen mit der Zeit schneller ausgeführt werden (Aufwärmphase: 274 ms → 34 ms). GC-Pausen beeinflussen die Latenz am Ende der Abfrage, werden aber durch die Entfernung von IQR-Ausreißern kompensiert. Der Abfrageoptimierer verarbeitet komplexe Aggregationspläne effizient, wodurch der Gewinn von agg_feature_sentiment resultiert. Die Kosten hierfür sind die Vorreservierung von 4 GB Heap-Speicher und der GC-Overhead.
Memgraph
Memgraph ist in C++ geschrieben. Es entsteht kein JVM-Overhead. Mit 415 MB für den vollständigen Datensatz ist es das kleinste der drei Systeme. Dank minimalem Abfrage-Overhead ist es bei einzelnen Einfügungen am schnellsten (1.427/s). Allerdings hinkt es beim gleichzeitigen Durchsatz hinterher (maximal 684 QPS). Es ist Bolt-kompatibel und funktioniert daher mit dem Neo4j-Treiber.
Benchmark-Methodik für Graphdatenbanken
Umfeld
- RunPod 8 vCPU (AMD EPYC x86_64), 32 GB RAM, Ubuntu 24.04 LTS
- Native Installation, kein Docker. Alle drei Datenbanken befinden sich auf demselben Rechner, Verbindungen über localhost.
- Python 3.12.3. Persistente Sitzungen für Single-Thread-Tests, Sitzungen pro Aufruf aus einem Verbindungspool für Multi-Thread-Tests.
Daten
- 120.000 synthetische Rezensionen, generiert aus Zipf- (Marken, Merkmale) und Poisson-Verteilungen (Entitäten, Beziehungen), fester Startwert = 42.
- 6 Knotentypen: Rezension, Produkt, Rezensent, Marke, Funktion, Kategorie
- 8 Kantentypen: ÜBER, VERFASST VON, IN DER KATEGORIE, ERSTELLT VON, HAT POSITIV, HAT NEGATIV, ERWÄHNT, VERGLEICHE MIT
Anfragen
12 Cypher-Vorlagen in 5 Kategorien: Punktsuche (3), 1-Hop-Traversierung (2), 2-Hop-Traversierung (2), Aggregation (3), Filter (1), vollständiger Scan (1). Jede parametrisierte Abfrage wird mit 10 verschiedenen Parameterwerten jeweils 100 Mal ausgeführt, was 1.000 Messungen pro Abfrage und Datenbank ergibt.
Die Parameter werden mittels Zipf-gewichteter Selektion aus dem gesamten ID-Raum ausgewählt, sodass sowohl beliebte als auch seltene Elemente getestet werden.
Drei Beispiele:
Punktsuche : Einzelnen Knoten anhand der indizierten ID abrufen
Zweistufiger Rundgang : Vom Markenprofil über die Produkte bis hin zu den Produktbewertungen
Aggregation : Vollständiger Graph-Scan mit Multi-Hop-Join und Berechnung
Messung
- Zeitaufwand:
time.perf_counter_ns(), 500 Aufwärmabfragen, mindestens 100 Ausführungen pro Abfrage - Statistik: 10.000 Bootstrap-Stichproben, 95%-Konfidenzintervall, Ausreißerbereinigung (Faktor 3,0). Es werden sowohl Rohdaten als auch gefilterte Daten angegeben.
- Speicher: Neo4j über JMX-Heap verwendet (VmRSS ist bedeutungslos, da die JVM vorab zuweist), FalkorDB über Redis
used_memory_rss, Memgraph über/proc/{pid}/statusVmRSS.
Fairness
- Gleiche Verbindungspoolgröße, gleiche Anzahl an Aufwärmvorgängen, gleiche Cypher-Abfragen, gleiche Daten und gleiche Maschine in allen drei Datenbanken.
- Paralleler Test: 60 Sekunden anhaltende Last bei 1, 2, 4, 8, 16 und 32 Threads mit einer festen Poolgröße von 32. Abfragemix: 40 % 1-Hop-Traversierung, 30 % 2-Hop-Traversierung, 20 % Aggregation, 10 % 3-Hop-Traversierung.
getestete Datenbanken
Einschränkungen
Einzelner Rechner, einzelner Knoten pro Datenbank. Keine Benchmarks für verteilte Systeme oder Cluster. Neo4j Enterprise Clustering und Memgraph-Replikation werden nicht berücksichtigt.
Synthetische Daten mit Verteilungen, die von echten Amazon-Rezensionen abgeleitet wurden. Entsprechen möglicherweise nicht den spezifischen Arbeitslastmustern in der Produktion.
Nicht gemessen wurden: Festplattenpersistenz/Wiederherstellung, Volltextsuche, Graphalgorithmen (PageRank, Community-Erkennung) und schreibintensive Arbeitslasten (>50 % Schreibvorgänge).
Unterschiedliche Treiber: Neo4j und Memgraph nutzten den Neo4j-Python-Treiber, FalkorDB hingegen einen eigenen. Der Overhead-Unterschied betrug in Single-Thread-Tests weniger als 0,5 ms.
Abschluss
FalkorDB gewann 11 von 12 Abfragen, erreichte 6.693 Abfragen pro Sekunde (QPS) und startete in 1,1 ms. Für leseintensive Graph-Workloads ist es die schnellste Option in diesem Benchmark. Memgraph ist die speichereffizienteste Option (415 MB gegenüber 2,7 GB). Neo4j bietet das umfassendste Ökosystem: RBAC, Clustering, Monitoring und einen Abfrageoptimierer, der komplexe Aggregationspläne besser verarbeitet als beide Alternativen.
Die Architektur setzt die Grenzen. Verteilte Cluster, Graphen mit mehr als 1 Million Knoten und schreibintensive Workloads sind die Tests, die diese Rangliste durcheinanderbringen könnten.
Seien Sie der Erste, der kommentiert
Ihre E-Mail-Adresse wird nicht veröffentlicht. Alle Felder sind erforderlich.