Durabilidad de las bases medidas
Todas las bases se miden en modo persistente (datos escritos en disco, reproducidos al reiniciar).
Bases medidas
| Base | Versión medida | Edición o licencia | Protocolo | Mediciones |
|---|---|---|---|---|
| gDown | main @ 087a1a5, 2026-10-16 | JVM build, benchmark settings | Bolt | cargas |
| Neo4j | 5.26.31 community | Community (GPLv3) | Bolt | cargas |
| Memgraph | 3.13.1 | Community (BSL 1.1) | Bolt | cargas |
| FalkorDB | 0.0.1 on Redis 8.10.2 | SSPL 1.0 | RESP | cargas |
| ArcadeDB | 26.10.1 | Apache 2.0 | Bolt | cargas |
| TuGraph | 4.5.1 | Community (Apache 2.0) | Bolt | cargas |
| Apache AGE | 1.8.0 on PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2) | Apache 2.0 (PostgreSQL extension) | JDBC | cargas |
Cómo corre el banco
| Propiedad | Valor |
|---|---|
| Arquitectura | arm64 |
| Máquina | Apple M4 Max, 16 logical CPUs, 64 GB RAM; Docker 29.8.2 |
| Límites de los contenedores | 4 CPU, 8 GB de memoria por contenedor |
| Grafo de las cargas | 100,000 nodos, 1,000,000 relaciones, generados con una semilla fija |
| Rondas | 3 rondas completas; cada cifra es la mediana de las rondas |
| Clientes | Un cliente Java en el anfitrión; 1, 4, 8 clientes concurrentes según la carga |
| Protocolo | El transporte de cada base (tabla de arriba): Bolt en ambos lados para gDown y Neo4j; una vuelta de calentamiento antes de cada carga, no contada |
| Fechas | 2026-10-07 – 2026-10-15 |
Arranque, memoria, CPU y tamaño
Sin índice
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| Arranque hasta la primera respuesta | 0.6 | 4.2 | 1.4 | 0.8 | 2.5 | 1.5 | 1.9 |
| CPU media (100 % = un núcleo) | 166 | 179 | 199 | 97 | 94 | 101 | 109 |
| CPU pico | 401 | 384 | 408 | 155 | 212 | 408 | 244 |
| Memoria pico | 519 | 4,814 | 538 | 436 | 6,425 | 374 | 477 |
| Datos en disco | 176 | 836 | 389 | 39 | 83 | 165 | 529 |
Con índices en los identificadores
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| Arranque hasta la primera respuesta | 0.6 | 4.2 | 1.4 | 0.8 | 2.5 | 1.5 | 1.9 |
| CPU media (100 % = un núcleo) | 141 | 180 | 193 | 97 | 94 | 101 | 109 |
| CPU pico | 397 | 380 | 412 | 154 | 212 | 408 | 244 |
| Memoria pico | 978 | 4,813 | 505 | 429 | 6,425 | 374 | 477 |
| Datos en disco | 182 | 837 | 389 | 39 | 83 | 165 | 529 |
Arranque: desde docker run hasta la primera respuesta a RETURN 1, mediana de varios intentos, medido una vez y repetido en las dos configuraciones; las demás filas cubren toda la ejecución de las cargas. La CPU y el disco no se clasifican: una base que no escribe nada duradero tiene 0 MB en disco.
Lecturas complejas: latencia mediana — LDBC SNB Interactive
Las 29 consultas de la carga Interactive del Social Network Benchmark del LDBC (14 lecturas complejas, 7 lecturas cortas, 8 actualizaciones; Apache 2.0, sin cambios) se ejecutan todas sobre un grafo generado con el esquema SNB.
- 29 / 29 consultas ejecutadas: 14 lecturas complejas, 7 cortas, 8 actualizaciones
- 3 / 3 miembros de un clúster de 3 nodos devuelven el mismo número de filas en las 21 lecturas
- 18 ms mediana de una escritura mientras el líder confirma 1.365 (3.000 personas)
- 0 ms mediana de una lectura en un seguidor durante esas escrituras (percentil 95: 30 ms)
Todas las bases, 3,000 personas
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| complex-1 | 2.3 | 7.5 | – | – | 12.3 | – | – |
| complex-2 | 1.2 | 2.4 | 3.8 | 209.0 | 3.3 | – | – |
| complex-3 | 9.0 | 10.3 | 8.9 | – | 19.5 | – | – |
| complex-4 | 0.9 | 2.2 | 1.1 | 0.6 | 2.5 | – | 126.1 |
| complex-5 | 4.7 | 10.1 | 4.9 | 2.5 | 16169.2 | – | – |
| complex-6 | 4.1 | 5.3 | 2.6 | – | 10.4 | – | – |
| complex-7 | 0.8 | 2.1 | 1.4 | – | – | – | – |
| complex-8 | 0.6 | 1.5 | 1.6 | 0.6 | 1.7 | – | – |
| complex-9 | 6.0 | 5.8 | 16.9 | – | 16.6 | – | – |
| complex-10 | 1.1 | 4.8 | – | – | – | – | – |
| complex-11 | 0.9 | 2.4 | 1.4 | 0.6 | 2.5 | – | – |
| complex-12 | 1.7 | 2.6 | 4.4 | – | 3.1 | – | – |
| complex-13 | 0.9 | 1.6 | – | – | 1.2 | – | – |
| complex-14 | 0.8 | 2.2 | – | – | 1861.0 | – | – |
Un guion: la base rechaza la consulta, supera su tiempo límite o devuelve un número de filas distinto al de Neo4j (su tiempo no significaría nada). Caso por caso:
Todas las bases, 30,000 personas
- 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
Mediana sobre 5 personas tras una vuelta de calentamiento, una pasada por base, en contenedores limitados como en la tabla de propiedades; cada base se consulta por su propio transporte (Bolt en ambos lados para gDown y Neo4j: el viaje de ida y vuelta cuenta en los dos lados). «< 1 ms»: la mediana se redondea a cero milisegundos. Lecturas cortas: mediana por debajo del milisegundo para gDown (0,5 a 0,7 ms) frente a 0,7 a 1 ms para Neo4j, mismo protocolo en ambos lados.
Con 3.000 personas (90.000 nodos y 470.000 relaciones, cargados por Raft en 16 s), las medianas quedan por debajo de 60 ms. Dos optimizaciones descubiertas por esta prueba: complex-1 pasó de 0,6 s a 34 ms y complex-14 de 2 s a 8 ms.
Resultados no oficiales: estas cifras se derivan de la carga LDBC SNB Interactive y no han sido auditadas por el LDBC (Linked Data Benchmark Council). Los datos los genera la prueba, no el Datagen del LDBC: los tiempos no son comparables con los resultados publicados del LDBC. Una sola ejecución por configuración. La prueba también encontró dos defectos, ya corregidos.
Fuente: gluonify-gdown, README e informes de LdbcSnbTest y LdbcClusterTest.
La cobertura de Cypher (el TCK de openCypher en cada base) está en la página de comparación.
Latencia y rendimiento, carga por carga
Mismo grafo, mismas consultas y misma máquina para cada base de la tabla de arriba: las cifras siguientes son la mediana de las rondas de la tabla de propiedades, medidas en arm64.
La latencia es la mediana (p50) en milisegundos, cuanto menos mejor; las cargas con varios clientes están en peticiones por segundo, cuanto más mejor. El mejor valor de cada fila está en negrita. No se ajusta nada más allá de los valores por defecto de cada imagen; gDown corre en la JVM con un heap de 6 GB y una caché de páginas de 2 GB, Neo4j con un heap de 4 GB y una caché de páginas de 2 GB. Cada ejecución parte de un contenedor nuevo, carga el grafo por lotes UNWIND, comprueba que las bases coinciden en los resultados y luego mide.
Sin índice
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| Lectura por identificador | 0.29 | 0.74 | 0.56 | 0.18 | 0.86 | 0.49 | 0.24 |
| Lectura por propiedad | 11.7 | 7.93 | 7.05 | 2.39 | 0.42 | 0.47 | 0.25 |
| Rango sobre una propiedad (100 valores) | 17.4 | 10.8 | 11.6 | 3.11 | 23.7 | 76.7 | 0.26 |
| Conteo de una etiqueta | 0.38 | 0.74 | 4.03 | 0.19 | 0.46 | 97.9 | 9.37 |
| 1 salto | 0.28 | 0.52 | 0.40 | 0.19 | 0.40 | 0.51 | 0.27 |
| 2 saltos distintos | 0.35 | 0.56 | 0.41 | 0.21 | 0.45 | 0.61 | 0.73 |
| 3 saltos distintos | 0.88 | 1.17 | 0.71 | 0.34 | 1.07 | 1.37 | 5.61 |
| Agrupación + top 10 | 3.94 | 10.9 | 32.6 | 14.9 | 8.74 | 145 | 62.5 |
| Filtro + agregado | 24.4 | 11.7 | 9.94 | 3.47 | 5.51 | 78.3 | 24.0 |
| Conteo de un patrón (todos los KNOWS entre personas) | 21.4 | 219 | 59.9 | 31.4 | 101 | 827 | 45.9 |
| Lecturas en caliente + un recorrido completo cada 100 | 0.32 | 0.57 | 0.41 | 0.19 | 0.41 | 0.53 | 0.31 |
| Primeras 10 filas de un resultado grande | 0.33 | 0.59 | 0.46 | 0.20 | 0.60 | 0.56 | 0.21 |
| Escritura: 1 nodo por petición | 0.47 | 0.57 | 0.57 | 0.35 | 0.56 | 0.49 | 0.26 |
| Escrituras durante un recorrido largo | 0.66 | 0.54 | 0.71 | 35.0 | 0.80 | 0.60 | 0.28 |
| 8 clientes: 1 salto | 16,239 | 8,437 | 9,811 | 28,458 | 10,525 | 4,249 | 16,372 |
| 4 clientes: escrituras | 6,801 | 5,223 | 3,260 | 4,652 | 3,364 | 3,675 | 9,280 |
ArcadeDB (indexado) se mide siempre con índice: sus identificadores internos impiden la búsqueda por id() de las demás columnas. Su columna está aquí para que no falte nada, pero sus relaciones sin índice comparan un índice con un recorrido: véase la tabla con índices para la comparación en igualdad de condiciones.
Con índices en los identificadores
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| Lectura por identificador | 0.30 | 0.73 | 0.50 | 0.18 | 0.86 | 0.49 | 0.24 |
| Lectura por propiedad | 0.27 | 0.52 | 0.38 | 0.20 | 0.42 | 0.47 | 0.25 |
| Rango sobre una propiedad (100 valores) | 0.32 | 0.48 | 0.37 | 0.21 | 23.7 | 76.7 | 0.26 |
| Conteo de una etiqueta | 0.26 | 0.46 | 3.77 | 0.17 | 0.46 | 97.9 | 9.37 |
| 1 salto | 0.26 | 0.46 | 0.34 | 0.19 | 0.40 | 0.51 | 0.27 |
| 2 saltos distintos | 0.32 | 0.51 | 0.36 | 0.21 | 0.45 | 0.61 | 0.73 |
| 3 saltos distintos | 0.82 | 1.00 | 0.51 | 0.33 | 1.07 | 1.37 | 5.61 |
| Agrupación + top 10 | 4.75 | 9.63 | 32.3 | 14.9 | 8.74 | 145 | 62.5 |
| Filtro + agregado | 21.2 | 16.5 | 9.82 | 3.41 | 5.51 | 78.3 | 24.0 |
| Conteo de un patrón (todos los KNOWS entre personas) | 20.9 | 225 | 62.4 | 31.3 | 101 | 827 | 45.9 |
| Lecturas en caliente + un recorrido completo cada 100 | 0.32 | 0.54 | 0.40 | 0.19 | 0.41 | 0.53 | 0.31 |
| Primeras 10 filas de un resultado grande | 0.34 | 0.55 | 0.46 | 0.21 | 0.60 | 0.56 | 0.21 |
| Escritura: 1 nodo por petición | 0.42 | 0.55 | 0.59 | 0.36 | 0.56 | 0.49 | 0.26 |
| Escrituras durante un recorrido largo | 0.66 | 0.56 | 0.60 | 35.0 | 0.80 | 0.60 | 0.28 |
| 8 clientes: 1 salto | 16,135 | 8,609 | 9,882 | 28,302 | 10,525 | 4,249 | 16,372 |
| 4 clientes: escrituras | 6,842 | 5,192 | 3,314 | 4,423 | 3,364 | 3,675 | 9,280 |
Carga del grafo
Sin índice
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| Tiempo de carga | 6.4 | 8.8 | 4.9 | 5.8 | 15.2 | 110.5 | 99.0 |
| Velocidad de carga | 172,107 | 125,063 | 224,642 | 188,301 | 72,488 | 9,954 | 11,115 |
Con índices en los identificadores
| Carga | gDown | Neo4j | Memgraph | FalkorDB | ArcadeDB | TuGraph | Apache AGE |
|---|---|---|---|---|---|---|---|
| Tiempo de carga | 10.9 | 11.0 | 6.0 | 40.8 | 15.2 | 110.5 | 99.0 |
| Velocidad de carga | 101,280 | 99,864 | 183,114 | 26,988 | 72,488 | 9,954 | 11,115 |
Qué conclusiones sacar
- FalkorDB es el más rápido en operaciones cortas (lecturas por identificador, saltos, escritura de un nodo) y en rendimiento con varios clientes, con el camino de cliente más corto (RESP). Mire «escrituras durante un recorrido largo»: sus escrituras esperan detrás de una lectura larga; no escribe nada duradero por defecto y su carga con índices es la más lenta.
- gDown es más rápido que Neo4j en la mayoría de las cargas (media geométrica por debajo de 1 en las dos configuraciones), carga más rápido y guarda sus datos en mucho menos espacio en disco. Está igual o más lento en las primeras filas de un resultado grande y en la escritura de un nodo: vea esas filas.
- Frente a Memgraph, gDown gana en agrupaciones, conteos de etiqueta y rendimiento con 8 clientes, y pierde en lecturas cortas, saltos y escrituras. Memgraph no fuerza sus confirmaciones a disco cada vez, a diferencia de gDown y Neo4j.
- ArcadeDB, medido siempre con índice, es competitivo en lectura pero lento en rangos y en escrituras con varios clientes.
- Memoria: las bases que lo guardan todo en RAM (Memgraph, FalkorDB) usan menos. gDown y Neo4j corren aquí con heaps generosos, y gDown necesita mucho menos con un heap más pequeño para las mismas latencias (véase la medida nativa más arriba).
Lo que esta comparación no dice
- La durabilidad difiere: gDown y Neo4j sincronizan el disco en cada confirmación; Memgraph solo cada 100 000 transacciones; FalkorDB no escribe nada duradero por defecto; no se comprobaron los ajustes de las demás bases. Las filas de escritura no comparan, pues, la misma garantía.
- Las bases que hablan Bolt comparten el mismo controlador Java; FalkorDB se mide con un cliente RESP mínimo escrito para el banco, que acorta su camino en lectura (véase la columna de transporte).
- ArcadeDB se mide siempre con índice, en las dos tablas (sus identificadores internos impiden la búsqueda por id()); una base sin valor en una configuración no se midió en ella.
- El grafo cabe en memoria en todas. No se miden un grafo mayor que la RAM, la replicación, la recuperación ante fallos, la búsqueda vectorial, los algoritmos de grafos ni las lecturas durante escrituras concurrentes. Un solo nodo de cada base.
- ArcadeDB corre con un heap sin límite: su cifra de memoria no es comparable. Su imagen es una instantánea de desarrollo.
- Una máquina que no estaba en reposo, pocas rondas: cuente con ±10 % en cada celda.
Fuente: gluonify-gdown, los resultados en bruto de cada ronda (docs/bench) y scripts/bench-compare.py, ensamblados por un script de este sitio; el script del banco está en el mismo repositorio.