PRODPlataforma BaaS soberana europeaAbrir panel →

Rendimiento · 15 lectura mínima

Cómo comparamos un backend: una metodología repetible

Affane Daylami · Fondateur · 8 de julio de 2026

volver al blog

Una cifra de referencia sin un método no prueba nada. “p95 por debajo de X ms”, “arranque en frío menos de Y ms”; cualquiera puede escribir eso en una página de marketing. Lo que prueba algo es el método: el equipo utilizado, la duración de la prueba, el protocolo de medición y la posibilidad de que un tercero lo reproduzca de forma idéntica.

Este texto en inglés se generó automáticamente a partir del original en francés y aún no ha sido revisado.
Esta página fue traducida automáticamente. La versión en inglés es autorizada.

Este artículo responde a una pregunta específica (cómo comparar una API backend de forma reproducible) documentando el protocolo que aplicaremos en Aurabase antes de publicar cualquier cifra de rendimiento. No resultados: un método. Cualquier medición ya publicada en otra parte de este sitio (especialmente en nuestra página Rendimiento) que aún no se base en este protocolo debe tratarse como no verificada hasta nuevo aviso.

Lo esencial

Hasta la fecha, no existen resultados de rendimiento de Aurabase siguiendo un protocolo publicado y reproducible; este artículo documenta la metodología que aplicaremos para producirlos, no los resultados ya obtenidos. El repositorio ya contiene un conjunto de pruebas de 3 niveles: micro-benchmarks de Criterion.rs en 3 cajas, pruebas de carga k6 en 8 escenarios HTTP/WebSocket y un script de Python para una comparación directa entre Postgres y API con cálculo de percentiles. El protocolo completo (duración de la medición, percentiles en lugar de promedios, aislamiento del entorno, divulgación de versión y fecha) se basa en fuentes externas verificadas: PostgreSQL, Criterion.rs, k6 (Grafana), HdrHistogram, PlanetScale y Convex. Cualquier afirmación de rendimiento ya publicada en otra parte de este sitio sin que se relacione con este protocolo debe considerarse no verificada.

#
Postura editorial

¿Por qué no publicamos cifras desnudas?

Convex, editor de un backend responsivo de la competencia, se ha distanciado públicamente de lo que su equipo técnico llama la “guerra de gráficos de barras” entre proveedores de bases de datos. Su fórmula es directa: “Se trata de escalar el teatro, no escalar”: escalar el teatro, no un escalamiento real (stack.convex.dev/on-competitive-benchmarks, blog técnico de Stack, consultado el 23 de agosto de 2026).

Su argumento central: un punto de referencia que compara dos sistemas con diferentes garantías de coherencia, topología o modelo de precios a menudo no prueba lo mismo, incluso cuando afirma hacerlo: "el punto de referencia en realidad no está probando lo mismo". Este reflejo tiene un nombre en la industria: benchmarketing, publicando una cifra elegida por su efecto de marketing más que por su rigor metodológico.

Nuestra respuesta no es negarnos a medir: negarnos a publicar una cifra indefinidamente sería tan deshonesto como publicar una cifra sin fundamento. Se trata de documentar primero cómo mediríamos, con qué herramientas y bajo qué condiciones, antes de afirmar haber medido algo. Esto también es lo que distingue una comparación útil (como nuestra comparación Aurabase vs Appwrite, que documenta diferencias arquitectónicas verificables) de una comparación de cifras de rendimiento sin un protocolo común.

Esto es particularmente importante para un líder técnico o un CTO que debe defender una elección de backend en un comité técnico: una cifra que no puede atribuirse a un método no sobrevive a la primera pregunta, algo insistente. Un protocolo documentado se defiende por sí solo: puede mostrar el script, la versión probada y ejecutar la prueba nuevamente frente a alguien si es necesario.

#
Diagnóstico

Lo que hace que la mayoría de los benchmarks de backend sean engañosos

Surgen sistemáticamente dos errores: comparar diferentes topologías sin informarlo y medir la latencia de una manera que oculte exactamente las pausas que más le importan al usuario.

En el primer punto, PlanetScale documenta explícitamente su restricción de paridad de hardware: cada entorno comparado debe ejecutarse en recursos informáticos (vCPU, RAM) iguales o mayores que la instancia de referencia, en la misma región de la nube (planetscale.com/benchmarks, metodología “Telescope”, consultada el 23 de agosto de 2026). Sin esta disciplina, una brecha de latencia puede simplemente reflejar una máquina más grande, no una arquitectura más rápida.

El mismo principio se aplica al estado de la caché y a la topología de la red. Una instancia que acaba de iniciarse (caché de Postgres inactivo, grupo de conexiones vacío, plan de consultas aún no almacenado en caché) responde estructuralmente más lentamente que una instancia que se ha estado ejecutando durante una hora con una carga estable. Una consulta de la misma región que la base de datos responde estructuralmente más rápido que una consulta entre regiones. Dos puntos de referencia que no especifican ninguno de los dos simplemente no son comparables, incluso si muestran unidades idénticas.

En el segundo punto, la trampa se llama omisión coordinada. HdrHistogram, el proyecto de referencia sobre medición de latencia creado por Gil Tene, lo explica de esta manera: cuando un generador de carga espera la respuesta de una solicitud antes de enviar la siguiente (bucle cerrado), una pausa del servicio reduce automáticamente la cantidad de solicitudes enviadas durante la pausa y, por lo tanto, la cantidad de mediciones de alta latencia registradas (github.com/HdrHistogram/HdrHistogram, consultado el 23 de agosto de 2026). El proyecto ofrece un ejemplo concreto y cuantificado: en un sistema hipotético que muestrea su latencia cada 10 ms durante 200 segundos, una sola pausa de 100 segundos en mitad de la prueba es suficiente para producir, sin corrección, un histograma en el que aproximadamente el 99,99% de las respuestas parecen encajar en menos de 1 ms, aunque en esta única pausa haya transcurrido la mitad del tiempo real.

Trampa clásica

Una prueba de carga de circuito cerrado que solo envía una solicitud después de recibir la respuesta anterior sistemáticamente no representa pausas largas. El p99 que muestra puede ser mejor que la realidad experimentada por un usuario real, no porque el sistema sea rápido, sino porque el protocolo de medición "olvidó" enviar las consultas mientras estaba en pausa.

#
Estadísticas

Por qué miente el promedio: p50, p95, p99

Una latencia promedio puede parecer excelente cuando una de cada veinte solicitudes tarda cinco veces más. Esto es precisamente lo que revelan los percentiles y lo que el promedio oculta estructuralmente.

Mecánicamente, un percentil no tiene nada de misterioso: ordenar todas las latencias medidas en orden ascendente y luego tomar el valor en la posición correspondiente. De 1000 consultas ordenadas, p50 es el valor 500, p95 el 950, p99 el 990. Una sola solicitud anormalmente lenta entre 1000 es suficiente para hacer que el p99 se mueva; es precisamente su sensibilidad a casos raros lo que lo hace útil, donde esta misma solicitud aislada casi no tiene efecto en el promedio.

Signo revelador: el informe de texto que pgbench, la herramienta de referencia oficial de PostgreSQL, muestra de forma predeterminada proporciona un promedio y una desviación estándar , no percentiles (postgresql.org/docs/current/pgbench.html, consultado el 23 de agosto de 2026). Su documentación oficial también advierte: “Nunca creas en una prueba que se ejecute solo durante unos segundos”; nunca creas en una prueba que solo se ejecute durante unos segundos, lo cual se aplica tanto a la duración como a la métrica elegida.

k6, la herramienta de carga que utilizamos para el nivel 2 de nuestra suite, resuelve esto con umbrales expresados en percentiles: la sintaxis p(95)<500 define un criterio de aprobación/rechazo (el 95% de las solicitudes deben responder dentro de 500 ms) directamente en la configuración de prueba (grafana.com/docs/k6, consultado el 23 de agosto de 2026).

p50 (mediana)La mitad de las consultas son más rápidas que este valor.Oculta completamente la cola de distribución.
p951 de cada 20 consultas es más lentaZona donde aparecen los primeros usuarios insatisfechos
p991 de cada 100 consultas es más lentaMás sensible a la omisión coordinada si el protocolo está mal diseñado
#
Comprobado en código

Los 3 niveles de referencia ya presentes en nuestro repositorio

Publicar una metodología sin herramientas reales sería una forma más de teatro. La carpeta benchmarks/ en el repositorio de Aurabase ya contiene una suite de 3 niveles, inspirada en su estructura en la metodología pública Supabase: las herramientas existen, los resultados medidos y fechados aún no existen.

3
NIVELES DE PRUEBA
Micro, carga HTTP, comparación
3
CAJAS COMPARADAS
aura-crypto, aura-db-adaptadores, aura-core
8
GUIONES K6
7 conectados a Makefile, 1 en espera

Nivel 1: Micro-benchmarks Criterion.rs

Tres cajas del espacio de trabajo de carga tienen puntos de referencia vinculados a la CPU: aura-crypto (hash Argon2, JWT HS256 - generación, validación y firma para PostgREST, cifrado AES-GCM), aura-db-adapters (filtros de análisis y select en formato PostgREST - eq., gte., in.(), relación incrustada) y aura-core (serialización JSON, resolución schema_name, validación UUID).

libs/aura-crypto/benches/crypto_bench.rsrust
// Extracto real del repositorio.
let mut group = c.benchmark_group("jwt/hs256");

group.bench_function("generate", |b| {
    b.iter(|| jwt::generate_access_token(
        black_box(user_id), black_box(project_id),
        black_box("authenticated"), black_box(SECRET),
    ))
});

group.bench_function("validate", |b| {
    b.iter(|| jwt::validate_token(black_box(&token), black_box(SECRET)))
});

aura-db-adapters mide específicamente el costo de analizar consultas en formato PostgREST: cuatro casos para filtros (simple_4, complex_10, or_group, in_large_50 con 50 valores) y cuatro para select (columnas individuales, *, una relación incrustada, cinco incrustaciones). Este es el tipo de costo invisible en una prueba de carga global: una regresión en el análisis de un filtro or.(...) complejo no cambiaría casi nada en el p95 de un punto final poco utilizado, pero sería mensurable en un punto final con mucho tráfico; de ahí el interés en aislarlo en un micro-benchmark en lugar de depender únicamente del nivel 2.

aura-core adopta un enfoque diferente: en lugar de medir el tiempo sin procesar, mide el rendimiento de (Throughput::Bytes) en la serialización JSON y deserialización de mensajes internos NatsRequest/NatsResponse intercambiados entre la puerta de enlace y los servicios, con tres tamaños de carga útil realistas (una solicitud mínima, una solicitud con un cuerpo JSON anidado, una respuesta de lista de 50 líneas).

libs/aura-core/benches/core_bench.rsrust
group.throughput(Throughput::Bytes(
    serde_json::to_vec(&small).unwrap().len() as u64
));
group.bench_function("NatsRequest/small", |b| {
    b.iter(|| serde_json::to_vec(black_box(&small)).unwrap())
});

Criterion.rs no se limita a cronometrar un bucle. Primero ejecuta una fase de calentamiento para llenar los cachés de CPU/OS, detecta valores atípicos con una versión modificada del método de Tukey (sin excluirlos del conjunto de datos), calcula intervalos de confianza mediante arranque en una gran cantidad de muestras remuestreadas y detecta regresiones de rendimiento entre dos ejecuciones mediante la prueba estadística de Student, con un umbral de ruido configurable (generalmente ±1%) para ignorar variaciones que no son estadísticamente significativas (bheisler.github.io/criterion.rs/book/analysis.html, consultado el 23 de agosto de 2026).

Reproducible localmente

Cada ejecución de Criterion genera un informe HTML detallado en target/criterion/: distribuciones, gráficos de regresión y comparación con la ejecución anterior. Es esta relación, no sólo una línea terminal, la que una metodología seria debe permitir regenerar.

Nivel 2: prueba de carga k6

Ocho scripts k6 cubren la puerta de enlace en el lado del plano de datos: health (línea base de latencia), auth-flow (registro → inicio de sesión → actualización → cierre de sesión), crud-read y crud-write, storage (carga/descarga), realtime-ws, breakpoint (aumento de carga hasta falla) y supabase-compare. Siete están conectados a un objetivo Makefile dedicado: supabase-compare.js existe en el repositorio pero aún no tiene un objetivo, una situación que este artículo documenta tal como está en lugar de disfrazarla.

benchmarks/k6/scenarios/crud-read.jsjavascript
export const options = {
  scenarios: {
    crud_read: {
      executor: 'ramping-vus',
      startVUs: 10,
      stages: [
        { duration: '30s', target: 50 },
        { duration: '1m', target: 200 },
        { duration: '30s', target: 0 },
      ],
    },
  },
  thresholds: THRESHOLDS_READ,
}

La configuración compartida define umbrales por tipo de operación. Estos son criterios de aprobación/rechazo que la prueba verifica cada vez que se ejecuta, no resultados ya medidos:

Lectura (OBTENER)p95 < 500 ms · p99 < 1000 msConfigurar k6 (benchmarks/k6/lib/config.js)
Escritura (POST/PARCHE)p95 < 300 ms · p99 < 1000 msConfigurar k6
Autenticación (iniciar sesión/actualizar)p95 < 300 ms · p99 < 1000 msConfigurar k6
Almacenamiento (carga/descarga)p95 < 500 ms · p99 < 2000 msConfigurar k6
Tasa de error, todos los escenarios< 1 %Configurar k6
Se encontró una inconsistencia al escribir este artículo.

El README.md en la carpeta benchmarks/ documenta un umbral de lectura de p95 en < 200ms ("Supabase SLO"), mientras que el umbral realmente aplicado en benchmarks/k6/lib/config.js, el que ejecuta la prueba, es p(95)<500. Los dos archivos se derivan uno del otro. Este es un ejemplo concreto, encontrado al leer el código fuente de este artículo, de por qué un protocolo debería tener una única fuente de verdad versionada en lugar de estar documentada en dos lugares: sin ella, incluso un equipo que intenta ser riguroso termina publicando umbrales contradictorios.

Nivel 3: comparación directa entre PostgreSQL y API

Un script de Python (direct_vs_api.py) mide la sobrecarga real de la puerta de enlace + capa de servicio comparando solicitudes psycopg2 directas con llamadas HTTP en la misma operación: lista, lectura única por identificación, lectura filtrada y ordenada. Cada medición sigue un calentamiento de 10 iteraciones antes del ciclo cronometrado, luego calcula el promedio, p50, p95, p99 y un rendimiento en operaciones por segundo.

benchmarks/comparison/direct_vs_api.pypython
def percentile(data, p):
    k = (len(data) - 1) * (p / 100)
    f = int(k)
    c = f + 1
    if c >= len(data):
        return data[f]
    return data[f] + (k - f) * (data[c] - data[f])

Un segundo script (aurabase_vs_supabase.py) aplica la misma lógica de calentamiento y cálculo de percentiles a una comparación directa con una instancia local de Supabase (Supabase CLI, localhost:54321 de forma predeterminada): la misma máquina, la misma red local para ambos, exactamente la disciplina de paridad de entorno que PlanetScale documenta para sus propias comparaciones.

Un script de orquestación (collect_baseline.sh, destino bench-baseline de Makefile) conecta los tres niveles: Criterion en las 3 cajas, un subconjunto de los escenarios k6 (health y crud-read hoy, no los 8 todavía), luego la comparación de Python, y escribe registros, informes JSON y Criterion HTML en una carpeta con marca de tiempo única: benchmarks/results/AAAAMMJJ_HHMMSS/. Éste es exactamente el reflejo de la divulgación fechada, en una sola tirada reproducible, que la siguiente sección formaliza en un protocolo completo.

#
Metodología

El protocolo que aplicaremos antes de publicar una figura

Ocho compromisos, cada uno de ellos anclado en una práctica ya documentada por una herramienta o proyecto de terceros reconocido, no inventado para la ocasión.

  1. Precalentamiento separado de la medición. Criterion.rs llena los cachés de CPU/OS antes de cronometrar; pgbench recomienda explícitamente no creer nunca en una carrera que dura sólo unos segundos.
  2. Duración fija, no un número fijo de iteraciones. Una carga necesita tiempo para converger; esta es la función de stages k6 y el indicador -T de pgbench.
  3. Percentiles, nunca solo el promedio, y vigilancia activa en caso de omisión coordinada si el generador de carga opera en un circuito cerrado.
  4. Entorno documentado en detalle: git commit del servicio probado, versión de PostgreSQL, especificación de hardware, versión de la herramienta de carga. PlanetScale documenta sus parámetros TPCC exactos (TABLES=20, SCALE=250, ~500 GB) precisamente por esta razón: sin estos detalles, nadie puede reproducir una ejecución.
  5. Resultados versionados y con marca de tiempo, nunca un solo número grabado en una página de marketing sin fecha. Las herramientas actuales ya están escritas en un archivo fechado; Será necesario extender este reflejo a cualquier medición publicada públicamente, con la región anfitriona documentada como cualquier otra variable ambiental (consulte nuestra guía sobre Soberanía de acogida de la UE, relevante en cuanto una cifra depende de una región determinada).
  6. Guiones y datos sin procesar publicados junto con el resultado agregado, no solo un promedio final. PlanetScale incluso invita a los lectores a informar de un error metodológico en una dirección específica: una postura que consideramos saludable y que queremos retomar.
  7. Rendimiento anunciado junto con la latencia, no solo uno u otro. Un sistema puede tener una latencia excelente con carga baja y colapsar en el rendimiento a medida que aumenta la concurrencia; eso es exactamente lo que el escenario breakpoint (escalar hasta fallar) de nuestra suite k6 está diseñado para revelar, y lo que la medición de microbenchmark Throughput::Bytes de Criterion captura a nivel de función.
  8. Brecha importante antes de anunciar una mejora. Una variación de un pequeño porcentaje entre dos ejecuciones puede ser ruido de medición en lugar de una ganancia real: Criterion.rs calcula la probabilidad de que la diferencia observada se deba al azar antes de calificarla como regresión o mejora. Una cifra aislada, sin esta verificación, es sólo una anécdota estadística.
#
Compromiso editorial

lo que no haremos

Esta lista cuenta tanto como el protocolo positivo anterior.

  • Comparar diferentes topologías (instancia autohospedada versus administrada, instancia fría versus precalentada) sin informarlo explícitamente.
  • Conservar la mejor racha de diez sin mencionar los otros nueve.
  • Publicar una figura sin fecha, sin versión de servicio, sin guion de reproducción.
  • Volver a publicar una figura de marketing existente siempre que no se remonta a este protocolo.
  • Compararnos con un competidor basándose en una cifra bruta de rendimiento si ese competidor no publica su propia metodología de manera equivalente: una cifra versus silencio no es una comparación, es un eslogan.
Un ejemplo concreto, ya corregido internamente

Se distribuyó una cifra como “arranque en frío en menos de 1 ms” sin estar respaldada por un punto de referencia reproducible. Ahora se trata internamente como no compatible y no debe leerse como una característica medida del producto hasta que cualquier medición fechada, con metodología publicada, lo confirme. Este es precisamente el tipo de afirmación que este protocolo pretende evitar que se repita.

#
repetible

El protocolo mínimo para comparar cualquier backend

Este protocolo no depende de ninguna herramienta específica de Aurabase; puede aplicarlo a su propia API hoy.

  1. Establezca la carga antes de la herramienta: solo lectura, escritura, combinación realista para su aplicación, no una proporción genérica copiada de otro proyecto.
  2. Separe explícitamente la fase de precalentamiento de la fase de medición.
  3. Realice la prueba durante el tiempo suficiente: minutos, no segundos.
  4. Medir en percentiles (p50/p95/p99), nunca en promedio solo.
  5. Verifique que su generador de carga no esté en circuito cerrado, o corrija la omisión de coordinación en el análisis.
  6. Aísle el entorno bajo prueba: sin vecinos ruidosos ni tareas en segundo plano que compitan entre sí.
  7. Publique la versión probada, la fecha, las especificaciones de hardware y el script, no solo el resultado final.

En una base básica de Postgres, este protocolo requiere un comando pgbench: 20 clientes simultáneos distribuidos en 4 subprocesos, durante 5 minutos, con un informe de progreso cada 10 segundos:

terminalbash
# Inicialice el conjunto de datos de prueba (factor de escala>= número de clientes)
pgbench -i -s 50 ma_base

# -c clientes concurrentes, -j subprocesos, -T duración en segundos, -P intervalo de informes
pgbench -c 20 -j 4 -T 300 -P 10 ma_base
#
Herramientas

Herramientas de referencia, por nivel

Cinco herramientas, cada una adaptada a un nivel diferente de la pila; ninguna reemplaza a las demás.

Micrófono (función)Criterio.rsCPU pura, estadísticas de arranque
consulta SQLbanco de pgbTransacción tipo TPC-B, tps y latencia
Carga HTTP/WSk6 (Grafana)Percentiles, umbrales de aprobación/reprobación
OLTP a escalasysbench + TPCC (Metodología del telescopio)QPS, coste por rendimiento
Corrección de mediciónHdrHistogramaCompensa la omisión coordinada
#
Preguntas frecuentes

Preguntas frecuentes

¿Por qué Aurabase aún no publica cifras de referencia?+
Porque hasta la fecha no se han medido cifras de rendimiento según un protocolo publicado y reproducible. Una cifra como “arranque en frío menos de 1 ms”, por ejemplo, circuló sin estar respaldada por un punto de referencia reproducible: hoy en día se considera infundada y no debe leerse como una característica medida del producto. Este artículo documenta el protocolo que seguiremos antes de publicar un resultado, precisamente para evitar repetir este tipo de afirmaciones.
¿Qué es un percentil p95 o p99 y por qué no el promedio?+
El p95 es el tiempo de respuesta por debajo del cual se encuentran el 95% de las solicitudes; por lo tanto, 1 de cada 20 solicitudes es más lenta. El p99 eleva este umbral a 1 solicitud entre 100. El promedio oculta estas solicitudes lentas porque las diluye en la masa de solicitudes rápidas; Los percentiles aíslan la cola de la distribución que los usuarios realmente notan.
¿Qué es la “omisión coordinada”?+
Se trata de un sesgo de medición descrito por el proyecto HdrHistogram: cuando una herramienta de carga espera la respuesta a una solicitud antes de enviar la siguiente (bucle cerrado), una pausa del servicio reduce mecánicamente el número de solicitudes lentas registradas durante esta pausa. El resultado final puede mostrar una latencia mucho mejor que la que experimentó un usuario real.
¿Podemos reproducir estas pruebas nosotros mismos?+
El protocolo descrito aquí (percentiles, precalentamiento separado, entorno documentado, resultados fechados) es aplicable a cualquier API, con herramientas públicas (k6, pgbench, Criterion.rs, sysbench). Las herramientas internas de Aurabase (la carpeta de puntos de referencia/repositorio) se utilizan actualmente para el desarrollo y aún no están empaquetadas como una suite pública de un solo clic. Cree un proyecto para probar su propia carga en la API de Aurabase con sus propios scripts k6.
¿Cuál es la diferencia entre un percentil medido y un umbral SLA?+
Un percentil (p95, p99) es una estadística calculada a posteriori sobre mediciones reales. Un umbral SLA (o un umbral k6 como p(95)<500) es un objetivo establecido de antemano, que la prueba verifica en modo pasa/falla. Confundir ambos lleva a presentar un objetivo no alcanzado como un resultado obtenido; esta es precisamente la distinción que este protocolo requiere que se mantenga explícita con cada cifra publicada.
¿Por qué medir el rendimiento además de la latencia?+
Un sistema puede responder rápidamente con una carga baja y ver cómo su latencia se degrada repentinamente una vez que se excede un umbral de concurrencia; la latencia por sí sola no muestra dónde está este umbral. La medición del rendimiento (solicitudes o bytes por segundo) junto con la latencia revela este punto de inflexión, que es algo para lo que el escenario de punto de interrupción de nuestra suite k6 está diseñado específicamente para encontrar.

¿LISTO PARA IMPLEMENTAR?

Tu backend en cinco minutos.

No se requiere tarjeta de crédito · 500 MB gratis · 50,000 MAU