Cómo está hecho y qué mide de verdad
Esta herramienta ejecuta operaciones reales contra Firestore y MongoDB desde un servidor, mide cuánto tarda cada una y transmite las muestras al navegador mientras la corrida sigue. No simula nada.
La parte interesante no es el resultado. Es cuántas maneras hay de medir mal sin enterarse, y qué se hizo en cada caso para no caer.
Un benchmark honesto empieza diciendo qué no mide
Cada muestra incluye el viaje de red hasta la base. Desde Honduras ese viaje ronda los 50 ms, así que la operación de MongoDB cuesta entre 2 y 6 ms y todo lo demás es distancia. Un número sin sus condiciones no significa nada.
01 · Arquitectura
Un solo tipo sostiene todo
El dominio declara un puerto y nada más. La isla de interfaz conoce ese tipo y ninguna otra cosa: no sabe que existe Firestore, ni MongoDB, ni HTTP. Pasar del adaptador simulado al real de Firestore fue cambiar una línea en el composition root.
Es la prueba que vale la pena mostrar: si agregar un motor obligara a tocar la interfaz, el diseño estaría roto.
El runner secuencial también cumple ese puerto. Por eso la interfaz no distingue una corrida de un motor de una de varios: para ella siempre es un único ejecutor.
02 · Recorrido
Qué pasa al apretar ejecutar
La entrada de red se valida elemento por elemento antes de tocar nada. Después los motores corren uno detrás del otro, y cada muestra vuelve al navegador apenas se mide.
03 · Método
Qué le pasa a cada muestra
El calentamiento existe porque abrir la conexión y llenar cachés cuesta, y ese costo se paga una sola vez. Si entrara en la medición, el primer valor arrastraría la media y ensuciaría la cola.
04 · Decisiones
Seis maneras de medir mal
Cada una se recorrió por el camino equivocado primero. Están acá porque el error era silencioso: los números salían, se veían bien, y estaban mal.
01
El ganador se decide por p95, no por la media
La cola es lo que el usuario siente. Una media buena con una cola mala se percibe como una aplicación lenta, y al revés no pasa. Un empate exacto o un motor único no dan ganador.
02
El gráfico usa escala logarítmica
Firestore ronda los 200 ms y MongoDB los 2 ms de trabajo real. En escala lineal el segundo sería una raya invisible pegada al eje.
03
El rendimiento sale del reloj de la fase, no de la media
Invertir la media da un número que se rompe al subir la concurrencia: medido, pasar de 1 a 6 workers bajaba el valor reportado de 6.47 a 3.67 op/s mientras el rendimiento real subía de 5.65 a 19.9. Latencia y rendimiento son preguntas distintas; nunca derivar una de la otra.
04
deleteOne siembra iteraciones más calentamiento
Con solo las iteraciones, el calentamiento consume los primeros documentos y la medición vuelve a borrarlos. Firestore no falla al borrar algo inexistente, así que el contador de errores queda en cero y los números salen limpios y falsos.
05
Cada operación tiene su colección, con nombre estable
Un índice compuesto en Firestore se define por colección: un nombre con marca de tiempo obligaría a crearlo de nuevo en cada corrida. La colección se vacía al entrar y al salir de la fase — al entrar también, porque una corrida cortada a la mitad deja documentos y la siguiente mediría contra basura.
06
Los índices se igualan de los dos lados
Firestore indexa cada campo por su cuenta; MongoDB solo el _id. Por eso el adaptador de MongoDB crea el índice compuesto al sembrar: sin él, la consulta filtrada haría un escaneo completo y la comparación mediría un índice faltante, no un motor.
05 · Resultados
Lo medido, y cómo leerlo
30 iteraciones, documentos de 1024 B, concurrencia 1, ejecutado desde Honduras. Cero errores en las diez fases. p95 en milisegundos, más corto es mejor.
| Motor | insertOne | findById | queryFiltered | updateOne | deleteOne |
|---|---|---|---|---|---|
| Firestorenam5 · multirregión | 127.8 | 99.7 | 154.9 | 120.2 | 113.5 |
| MongoDBAtlas M0 · región única | 54.3 | 52.1 | 52.7 | 55.8 | 56.1 |
Esto no dice que MongoDB sea 2 o 3 veces más rápido
La prueba está en la propia tabla. Firestore hace consenso entre regiones antes de confirmar una escritura, así que si el motor mandara, la brecha en escrituras tendría que ser mucho mayor que en lecturas.
Y no lo es: va de 1.9 veces en findById a 2.4 veces en insertOne. Un factor parejo en todas las operaciones no puede ser el motor. Es la red.
Desplegado en Vercel la función mide desde iad1, mucho más cerca de ambas bases, y estos números cambian. Por eso la región está fijada en la configuración: si el proveedor ubicara la función lejos, el benchmark dejaría de medir la base para medir la topología.
06 · Glosario
Cada término, una vez
Las mismas definiciones que aparecen en los tooltips de la consola. Una sola redacción para las dos superficies: una métrica explicada dos veces termina significando dos cosas.
- Latencialatency
- Tiempo entre pedir la operación y recibir su confirmación, medido en el servidor. Incluye el viaje de red hasta la base, no solo el trabajo del motor.
- p50 · medianap50
- La mitad de las muestras tardó menos que este valor. Describe la ejecución típica, no la peor.
- p95p95
- El 95 % de las muestras tardó menos que este valor. Es la cola que el usuario percibe como lentitud, y por eso el ganador de cada operación se decide aquí y no por la media.
- p99p99
- El 1 % más lento. Con pocas muestras es muy inestable: un solo pico lo mueve entero.
- Mediamean
- Promedio de todas las muestras. Una sola muestra extrema la arrastra hacia arriba, así que puede esconder una cola mala tanto como inventarla.
- Máximomax
- La muestra más lenta de la fase. Dice hasta dónde llegó el peor caso; como es un único dato, no sirve para comparar motores.
- Rendimientothroughput
- Operaciones completadas por segundo sobre el tiempo real de la fase. No es la inversa de la media: al subir la concurrencia cada operación tarda más y el rendimiento sube igual.
- Erroreserrors
- Operaciones que fallaron. No entran en los percentiles, así que las columnas de latencia describen únicamente lo que sí llegó a completarse.
- Iteracionesiterations
- Muestras medidas por cada motor y cada operación. Cuantas más, más confiable es la cola: con diez muestras el p95 es poco más que una anécdota.
- Calentamientowarmup
- Operaciones que se ejecutan y se descartan antes de empezar a medir, para que abrir la conexión y llenar cachés no se cuele en los números.
- Tamaño del documentodocumentSize
- Bytes aproximados del documento de prueba. Cuanto más crece, más pesan la red y la serialización frente al motor.
- Concurrenciaconcurrency
- Operaciones en vuelo al mismo tiempo. Con 1 se mide latencia pura; al subir, cada operación tarda más pero el trabajo total por segundo crece.
- Escala logarítmicalogScale
- Cada marca del eje multiplica por diez. En escala lineal, un motor de 2 ms al lado de uno de 200 ms sería una raya invisible.
07 · Límites
Lo que no puede afirmar
- Una corrida por motor a la vez. Las colecciones tienen nombre estable, así que dos ejecuciones simultáneas se pisarían. Es una herramienta de un operador a la vez.
- El M0 de Atlas comparte CPU. Su cola es más ruidosa: con diez iteraciones se vio un p95 de 835 ms sobre un p50 de 54 ms. Sacar conclusiones de la cola exige muestras largas.
- Firestore vive en nam5, que es multirregión. Cada escritura replica entre regiones de EE. UU. antes de confirmarse, así que no es comparable contra un cluster de región única sin decirlo en voz alta.
- Desplegado, la función mide desde iad1 y no desde Honduras. Los números de esta página cambian, y esa es justamente la idea.