gDown Performances

Même graphe, mêmes requêtes et même machine pour chaque base du tableau ci-dessus : les chiffres ci-dessous sont la médiane des tours du tableau des propriétés, mesurés sur arm64.

Durabilité des bases mesurées

Pour ces chiffres de performances, toutes les bases sont mesurées en mode persistant (données écrites sur disque, rejouées au redémarrage).

Bases mesurées

BaseVersion mesuréeÉdition ou licenceProtocoleMesures
gDownmain @ 087a1a5, 2026-10-16JVM build, benchmark settingsBoltcharges
Neo4j5.26.31 communityCommunity (GPLv3)Boltcharges
Memgraph3.13.1Community (BSL 1.1)Boltcharges
FalkorDB0.0.1 on Redis 8.10.2SSPL 1.0RESPcharges
ArcadeDB26.10.1Apache 2.0Boltcharges
TuGraph4.5.1Community (Apache 2.0)Boltcharges
Apache AGE1.8.0 on PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2)Apache 2.0 (PostgreSQL extension)JDBCcharges

Comment le banc tourne

PropriétéValeur
Architecturearm64
MachineApple M4 Max, 16 logical CPUs, 64 GB RAM; Docker 29.8.2
Limites des conteneurs4 CPU, 8 Go de mémoire par conteneur
Graphe des charges100,000 nœuds, 1,000,000 relations, engendrés avec une graine fixe
Tours3 tours complets ; chaque chiffre est la médiane des tours
ClientsUn client Java sur l'hôte ; 1, 4, 8 clients concurrents selon la charge
ProtocoleLe transport de chaque base (tableau ci-dessus) : Bolt des deux côtés pour gDown et Neo4j ; un tour de chauffe avant chaque charge, non compté
Dates2026-10-07 – 2026-10-15

Démarrage, mémoire, CPU et taille

Sans index

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
Démarrage jusqu'à la première réponse0.64.21.40.82.51.51.9
CPU moyen (100 % = un cœur)1661791999794101109
CPU crête401384408155212408244
Mémoire crête5194,8145384366,425374477
Données sur disque1768363893983165529

Avec index sur les identifiants

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
Démarrage jusqu'à la première réponse0.64.21.40.82.51.51.9
CPU moyen (100 % = un cœur)1411801939794101109
CPU crête397380412154212408244
Mémoire crête9784,8135054296,425374477
Données sur disque1828373893983165529

Démarrage : du docker run à la première réponse à RETURN 1, médiane de plusieurs essais, mesuré une fois et repris dans les deux configurations ; les autres lignes couvrent toute l'exécution des charges. Le CPU et le disque ne sont pas classés : une base qui n'écrit rien de durable a 0 Mo sur disque.

Lectures complexes : latence médiane — LDBC SNB Interactive

Les 29 requêtes de la charge Interactive du Social Network Benchmark du LDBC (14 lectures complexes, 7 lectures courtes, 8 mises à jour ; Apache 2.0, inchangées) tournent toutes sur un graphe engendré au schéma SNB.

  • 29 / 29 requêtes exécutées : 14 lectures complexes, 7 lectures courtes, 8 mises à jour
  • 3 / 3 membres d'un cluster à 3 nœuds renvoient les mêmes nombres de lignes pour les 21 lectures
  • 18 ms médiane d'une écriture pendant que le leader en acquitte 1 365 (3 000 personnes)
  • 0 ms médiane d'une lecture sur un suiveur pendant ces écritures (95e centile : 30 ms)

Toutes les bases, 3,000 personnes

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
complex-12.37.5––12.3––
complex-21.22.43.8209.03.3––
complex-39.010.38.9–19.5––
complex-40.92.21.10.62.5–126.1
complex-54.710.14.92.516169.2––
complex-64.15.32.6–10.4––
complex-70.82.11.4––––
complex-80.61.51.60.61.7––
complex-96.05.816.9–16.6––
complex-101.14.8–––––
complex-110.92.41.40.62.5––
complex-121.72.64.4–3.1––
complex-130.91.6––1.2––
complex-140.82.2––1861.0––

Un tiret : la base refuse la requête, dépasse son délai ou renvoie un nombre de lignes différent de Neo4j (son temps ne voudrait rien dire). Cas par cas :

Toutes les bases, 30,000 personnes

  • complex-1 : gDown 12.9 ms, Neo4j 51.5 ms
  • complex-2 : gDown 2.8 ms, Neo4j 2 ms
  • complex-3 : gDown 15.1 ms, Neo4j 13.3 ms
  • complex-4 : gDown 1.6 ms, Neo4j 1.7 ms
  • complex-5 : gDown 19.5 ms, Neo4j 16.9 ms
  • complex-6 : gDown 6.7 ms, Neo4j 7 ms
  • complex-7 : gDown 1.4 ms, Neo4j 1.4 ms
  • complex-8 : gDown 0.8 ms, Neo4j 1 ms
  • complex-9 : gDown 15.1 ms, Neo4j 8.5 ms
  • complex-10 : gDown 4.4 ms, Neo4j 4.2 ms
  • complex-11 : gDown 1.9 ms, Neo4j 1.8 ms
  • complex-12 : gDown 2 ms, Neo4j 2.4 ms
  • complex-13 : gDown 0.9 ms, Neo4j 1 ms
  • complex-14 : gDown 4 ms, Neo4j 3.3 ms

Médiane sur 5 personnes après un tour de chauffe, un passage par base, dans des conteneurs limités comme dans le tableau des propriétés ; chaque base est interrogée par son transport (Bolt des deux côtés pour gDown et Neo4j : l'aller-retour est compté des deux côtés). « < 1 ms » : la médiane s'arrondit à zéro milliseconde. Lectures courtes : médiane sous la milliseconde pour gDown (0,5 à 0,7 ms) contre 0,7 à 1 ms pour Neo4j, même protocole des deux côtés.

À 3 000 personnes (90 000 nœuds et 470 000 relations, chargés par Raft en 16 s), les médianes restent sous 60 ms. Deux optimisations trouvées par ce test : complex-1 est passée de 0,6 s à 34 ms, complex-14 de 2 s à 8 ms.

Résultats non officiels : ces chiffres sont dérivés de la charge LDBC SNB Interactive et n’ont pas été audités par le LDBC (Linked Data Benchmark Council). Les données sont engendrées par le test, pas par le Datagen du LDBC : les temps ne sont pas comparables aux résultats LDBC publiés. Une seule exécution par configuration. Le test a aussi trouvé deux défauts, corrigés.

Source : gluonify-gdown, README et rapports de LdbcSnbTest et LdbcClusterTest.

La couverture de Cypher (le TCK openCypher sur chaque base) est sur la page de comparaison.

Latence et débit, charge par charge

Même graphe, mêmes requêtes et même machine pour chaque base du tableau ci-dessus : les chiffres ci-dessous sont la médiane des tours du tableau des propriétés, mesurés sur arm64.

La latence est la médiane (p50) en millisecondes, plus bas = mieux ; les charges à plusieurs clients sont en requêtes par seconde, plus haut = mieux. La meilleure valeur de chaque ligne est en gras. Rien n'est réglé au-delà des défauts de chaque image ; gDown tourne sur la JVM avec un tas de 6 Go et un cache de pages de 2 Go, Neo4j avec un tas de 4 Go et un cache de pages de 2 Go. Chaque exécution part d'un conteneur neuf, charge le graphe par lots UNWIND, vérifie que les bases s'accordent sur les résultats, puis mesure.

Sans index

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
Lecture par identifiant0.290.740.560.180.860.490.24
Lecture par propriété11.77.937.052.390.420.470.25
Intervalle sur une propriété (100 valeurs)17.410.811.63.1123.776.70.26
Comptage d'une étiquette0.380.744.030.190.4697.99.37
1 saut0.280.520.400.190.400.510.27
2 sauts distincts0.350.560.410.210.450.610.73
3 sauts distincts0.881.170.710.341.071.375.61
Regroupement + top 103.9410.932.614.98.7414562.5
Filtre + agrégat24.411.79.943.475.5178.324.0
Comptage d'un motif (tous les KNOWS entre personnes)21.421959.931.410182745.9
Lectures chaudes + un parcours complet pour 1000.320.570.410.190.410.530.31
10 premières lignes d'un grand résultat0.330.590.460.200.600.560.21
Écriture : 1 nœud par requête0.470.570.570.350.560.490.26
Écritures pendant un long parcours0.660.540.7135.00.800.600.28
8 clients : 1 saut16,2398,4379,81128,45810,5254,24916,372
4 clients : écritures6,8015,2233,2604,6523,3643,6759,280

ArcadeDB (indexé) est toujours mesuré avec index : ses identifiants internes interdisent la recherche par id() des autres colonnes. Sa colonne est ici pour que rien ne manque, mais ses rapports sans index comparent un index à un parcours : voir le tableau avec index pour la comparaison à armes égales.

Avec index sur les identifiants

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
Lecture par identifiant0.300.730.500.180.860.490.24
Lecture par propriété0.270.520.380.200.420.470.25
Intervalle sur une propriété (100 valeurs)0.320.480.370.2123.776.70.26
Comptage d'une étiquette0.260.463.770.170.4697.99.37
1 saut0.260.460.340.190.400.510.27
2 sauts distincts0.320.510.360.210.450.610.73
3 sauts distincts0.821.000.510.331.071.375.61
Regroupement + top 104.759.6332.314.98.7414562.5
Filtre + agrégat21.216.59.823.415.5178.324.0
Comptage d'un motif (tous les KNOWS entre personnes)20.922562.431.310182745.9
Lectures chaudes + un parcours complet pour 1000.320.540.400.190.410.530.31
10 premières lignes d'un grand résultat0.340.550.460.210.600.560.21
Écriture : 1 nœud par requête0.420.550.590.360.560.490.26
Écritures pendant un long parcours0.660.560.6035.00.800.600.28
8 clients : 1 saut16,1358,6099,88228,30210,5254,24916,372
4 clients : écritures6,8425,1923,3144,4233,3643,6759,280

Chargement du graphe

Sans index

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
Temps de chargement6.48.84.95.815.2110.599.0
Débit de chargement172,107125,063224,642188,30172,4889,95411,115

Avec index sur les identifiants

ChargegDownNeo4jMemgraphFalkorDBArcadeDBTuGraphApache AGE
Temps de chargement10.911.06.040.815.2110.599.0
Débit de chargement101,28099,864183,11426,98872,4889,95411,115

Ce qu'il faut en retenir

  • FalkorDB est le plus rapide sur les opérations courtes (lectures par identifiant, sauts, écriture d'un nœud) et en débit à plusieurs clients, avec le chemin client le plus court (RESP). Regardez « écritures pendant un long parcours » : ses écritures attendent derrière une lecture longue ; il n'écrit rien de durable par défaut et son chargement avec index est le plus lent.
  • gDown est plus rapide que Neo4j sur la plupart des charges (moyenne géométrique sous 1 dans les deux configurations), charge plus vite et garde ses données dans bien moins d'espace disque. Il est égal ou plus lent sur les premières lignes d'un grand résultat et sur l'écriture d'un nœud : voyez ces lignes.
  • Face à Memgraph, gDown gagne sur les regroupements, les comptages d'étiquette et le débit à 8 clients, et perd sur les lectures courtes, les sauts et les écritures. Memgraph ne force pas ses validations sur disque à chaque fois, contrairement à gDown et Neo4j.
  • ArcadeDB, toujours mesuré avec index, est compétitif en lecture mais lent sur les intervalles et sur les écritures à plusieurs clients.
  • Mémoire : les bases qui gardent tout en mémoire vive (Memgraph, FalkorDB) en utilisent le moins. gDown et Neo4j tournent ici avec des tas généreux, et gDown se contente de bien moins avec un tas plus petit pour les mêmes latences (voir la mesure native plus haut).

Ce que cette comparaison ne dit pas

  • La durabilité diffère : gDown et Neo4j synchronisent le disque à chaque validation ; Memgraph seulement tous les 100 000 transactions ; FalkorDB n'écrit rien de durable par défaut ; les réglages des autres bases n'ont pas été vérifiés. Les lignes d'écriture ne comparent donc pas la même garantie.
  • Les bases qui parlent Bolt partagent le même pilote Java ; FalkorDB est mesuré avec un client RESP minimal écrit pour le banc, qui raccourcit son chemin en lecture (voir la colonne transport).
  • ArcadeDB est toujours mesuré avec index, dans les deux tableaux (ses identifiants internes interdisent la recherche par id()) ; une base sans valeur dans une configuration n'y a pas été mesurée.
  • Le graphe tient en mémoire pour toutes les bases. Un graphe plus grand que la RAM, la réplication, la reprise après panne, la recherche vectorielle, les algorithmes de graphe et les lectures pendant des écritures concurrentes ne sont pas mesurés. Un seul nœud de chaque base.
  • ArcadeDB tourne avec un tas non borné : son chiffre de mémoire n'est pas comparable. Son image est un instantané de développement.
  • Une machine qui n'était pas au repos, quelques tours : comptez ±10 % sur chaque cellule.

Source : gluonify-gdown, les résultats bruts de chaque tour (docs/bench) et scripts/bench-compare.py, assemblés par un script de ce site ; le script du banc est dans le même dépôt.