Forge / Linux · 17–18 Oct 2026
Benchmarks
El mismo trabajo y el mismo tráfico. Explora las mediciones, conoce el método y reproduce cada prueba.
Total.js 4 0.0.99 · Express 5.3.0 · Fastify 5.12.7 · generator 8.0.0 · Meteor 3.5.2 · AdonisJS 6.21.0 · NestJS · Express 12.1.3 · Total.js 5 0.0.19
Compara el mismo escenario
RSS durante la carga · MiB
Las barras muestran la mediana de tres repeticiones. Los extremos indican su mínimo y máximo. La memoria es el RSS del proceso en MiB; todos los ejes parten de cero. El orden es fijo, no una clasificación.
| Framework | RSS inicial · MiB | RSS en carga · MiB | RSS tras la carga · MiB | CPU · % | Latencia p99 · ms | Cobertura del objetivo · % | Pruebas saludables |
|---|---|---|---|---|---|---|---|
| Total.js 4 | 61.0 [60.9–61.1] | 159.3 [150.1–167.0] | 174.3 [172.9–174.5] | 7.9 [7.8–8.2] | 5.0 [5.0–5.0] | 100.0 [100.0–100.0] | 3/3 |
| Total.js 5 | 62.8 [62.8–63.2] | 165.7 [164.9–166.7] | 173.8 [173.1–174.3] | 8.2 [8.1–8.2] | 6.0 [6.0–6.0] | 100.0 [100.0–100.0] | 3/3 |
| Express | 74.1 [73.9–74.2] | 90.8 [90.4–91.5] | 90.9 [90.5–91.6] | 7.3 [7.1–7.6] | 5.0 [4.0–5.0] | 100.0 [100.0–100.0] | 3/3 |
| Fastify | 75.9 [75.4–76.8] | 91.2 [91.0–91.6] | 91.2 [91.0–91.6] | 4.9 [4.9–5.0] | 3.0 [3.0–3.0] | 100.0 [100.0–100.0] | 3/3 |
| Node.js http | 50.2 [50.2–50.2] | 67.9 [67.5–69.8] | 67.9 [67.7–70.0] | 4.4 [4.4–4.5] | 3.0 [3.0–3.0] | 100.0 [100.0–100.0] | 3/3 |
| Meteor | 124.3 [123.4–125.5] | 168.6 [167.6–171.1] | 169.0 [168.5–172.3] | 12.8 [12.7–12.8] | 10.0 [8.0–18.0] | 100.0 [100.0–100.0] | 3/3 |
| AdonisJS | 114.3 [113.6–115.4] | 145.3 [144.6–149.7] | 145.3 [144.6–149.6] | 10.7 [10.4–10.7] | 6.0 [6.0–7.0] | 100.0 [100.0–100.0] | 3/3 |
| NestJS · Express | 100.4 [99.3–101.3] | 129.6 [129.4–130.0] | 129.8 [129.4–130.2] | 8.5 [8.5–8.6] | 5.0 [5.0–13.0] | 100.0 [100.0–100.0] | 3/3 |
Node.jsTotal.js 4 · v24.14.1 Total.js 5 · v24.15.0 Express · v24.14.1 Fastify · v24.14.1 Node.js http · v24.14.1 Meteor · v24.15.0 AdonisJS · v24.15.0 NestJS · Express · v24.15.0 | |||||||
Se muestra mediana [mínimo–máximo] entre repeticiones. Cada RSS procede de la mediana de su fase; los picos muestreados quedan en los datos originales. La fase inicial se mide después de comprobar las respuestas, no sin peticiones previas. La CPU es un porcentaje de una CPU lógica durante la ventana muestreada. El p99 describe peticiones completadas; léelo junto a los errores y la cobertura del objetivo.
La memoria durante una medición
Un proceso nuevo, muestreado cada segundo. Las franjas indican carga y recuperación; antes de la carga hay calentamiento y reposo. El RSS incluye runtime, heap y memoria nativa. No equivale al heap de JavaScript en uso.
Descargar el kit y preparar tu equipo
Ejecutar después de preparar el kit
docker run --rm --platform linux/amd64 --cpus 2 --memory 2g --memory-swap 2g --pids-limit 256 --read-only --network none --user "$(id -u):$(id -g)" --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 -v "$PWD/results:/results" forge-benchmark-local node benchmarks/v2/run.cjs --frameworks totaljs --workloads hello --rates 1000 --seconds 60 --warmup 15 --rest 30 --reps 3 --connections 32 --out /results/my-run.jsonEl comando usa la suite congelada de la ejecución elegida. Iguala hardware, límites y actividad de fondo antes de comparar una nueva ejecución. Al terminar, verifica con su v2/verify.cjs correspondiente.
Cómo interpretar el resultado
Compara la misma carga al mismo ritmo y consulta conjuntamente latencia, CPU, memoria, errores y cobertura del objetivo. También influye la versión del runtime. Estas mediciones no demuestran que un framework consuma siempre menos recursos. Total.js 4 y 5 aparecen por separado, cada uno con la implementación y el runtime registrados.
Qué se ha medido
Ocho adaptadores, cuatro cargas y objetivos comunes de 100 y 1.000 peticiones/s: 192 mediciones. Cada medición inicia un proceso nuevo en producción: comprobación de respuesta, 1,5 s iniciales, 15 s de calentamiento, 6 s de reposo, 60 s de carga y 30 s de recuperación. Se conservan las tres repeticiones. Los adaptadores se ejecutaron uno a uno. Se comprueba el cuerpo completo de las respuestas antes y después de la carga; el generador solicita hasta 32 conexiones.
Total5 utiliza NEWSCHEMA compacto y controlador directo para validar JSON; el JSON sencillo se devuelve desde el controlador. Se incluyen escenarios completos registrados, sin escoger el mejor resultado numérico. Meteor usa su bundle de producción solo de servidor; NestJS usa su adaptador Express. Los validadores nativos cubren el cuerpo medido; las conversiones y el rechazo de entradas pueden diferir entre frameworks.
Entorno
Servidor Linux x64 compartido, Intel Core i7-6700. Cada contenedor de medición tenía un límite de 2 CPU lógicas y 2 GiB, sin red exterior ni puertos publicados. El generador y la dependencia simulada compartían contenedor. Total4, Express, Fastify y Node http utilizaron Node 24.14.1; Total5, Meteor, AdonisJS y NestJS, Node 24.15.0, la versión requerida por el bundle de Meteor. Los datos originales conservan el runtime de cada framework: las diferencias no pueden atribuirse solo al framework. Los servicios de producción del servidor siguieron funcionando.
Qué no demuestran estos resultados
Es un experimento con límite de tráfico y cliente de bucle cerrado, no una clasificación de capacidad máxima. Alcanzar el objetivo no demuestra cómo se comportan los adaptadores con llegadas independientes o saturación. Hubo cierta limitación de CPU por cuota, registrada en la revisión. Tres repeticiones cortas no demuestran estabilidad a largo plazo, ausencia de fugas de memoria, seguridad en producción, comportamiento de Flow ni consumo en Raspberry Pi. No se forzó el recolector de basura. El RSS puede seguir reservado al cesar el tráfico.
Una medición se considera saludable si las completadas alcanzan el 95 % del objetivo por duración del generador, el p99 no supera 250 ms y no hay errores, timeouts ni respuestas no-2xx. Este umbral no afirma que todos tengan la misma capacidad máxima.
Evidencia original
Comparación completa de frameworks
Revisión de integridad y entorno · Sumas SHA-256 · JSON · Markdown
Reproducir y comprobar
Utiliza una carpeta vacía con Docker (contenedores Linux), curl y tar. No necesitas Node.js en tu equipo: la comprobación de hash y las pruebas utilizan Node 24.15.0 dentro de Docker. La primera compilación descarga dependencias y construye Meteor, por lo que puede tardar varios minutos. La preparación requiere internet; los contenedores de pruebas no tienen red exterior. Cada escenario medido tarda unos seis minutos.
El kit ejecuta los ocho adaptadores con Node v24.15.0. Las mediciones publicadas conservan sus versiones originales, indicadas en la tabla.
Descargar el kit completo de pruebas
1. Descargar y preparar. El enlace incluye el programa de pruebas, los adaptadores y los locks; no necesitas instalar Forge ni clonar un repositorio. Desde una carpeta vacía, ejecuta estos comandos. Si descargas con el botón, conserva el nombre sources.tar.gz y omite curl.
curl --fail --location --output sources.tar.gz 'https://forge.totaljs.es/benchmarks/node-24.15.0/sources.tar.gz' &&
docker run --rm --platform linux/amd64 --network none -v "$PWD:/kit:ro" node:24.15.0-bookworm node -e 'const fs=require("node:fs"),crypto=require("node:crypto");if(crypto.createHash("sha256").update(fs.readFileSync("/kit/sources.tar.gz")).digest("hex")!=="65801cd865a3fc961e69ba8df421ed198acdc399d29934714fb954e4de1db651")throw Error("SHA-256 mismatch");' &&
tar -xzf sources.tar.gz &&
docker build --platform linux/amd64 -t forge-benchmark-local . &&
mkdir -p results
2. Comprobar la instalación (unos 15–30 segundos). Esta prueba breve genera smoke.json y verifica sus entradas; no es un resultado de rendimiento publicable.
docker run --rm --platform linux/amd64 --cpus 2 --memory 2g --memory-swap 2g --pids-limit 256 --read-only --network none --user "$(id -u):$(id -g)" --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 -v "$PWD/results:/results" forge-benchmark-local node benchmarks/v2/run.cjs --smoke --frameworks totaljs --workloads hello --rates 1000 --out /results/smoke.json
docker run --rm --platform linux/amd64 --cpus 2 --memory 2g --memory-swap 2g --pids-limit 256 --read-only --network none --user "$(id -u):$(id -g)" --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 -v "$PWD/results:/results" forge-benchmark-local node benchmarks/v2/verify.cjs /results/smoke.json --allow-smoke
3. Ejecutar y verificar la medición elegida. El resultado se guarda en results/my-run.json dentro de la carpeta benchmarks seleccionada. El programa no sobrescribe archivos existentes: usa otro nombre para repetir. La verificación comprueba integridad y entradas, no que las cifras coincidan con las publicadas.
docker run --rm --platform linux/amd64 --cpus 2 --memory 2g --memory-swap 2g --pids-limit 256 --read-only --network none --user "$(id -u):$(id -g)" --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 -v "$PWD/results:/results" forge-benchmark-local node benchmarks/v2/run.cjs --frameworks totaljs --workloads hello --rates 1000 --seconds 60 --warmup 15 --rest 30 --reps 3 --connections 32 --out /results/my-run.json
docker run --rm --platform linux/amd64 --cpus 2 --memory 2g --memory-swap 2g --pids-limit 256 --read-only --network none --user "$(id -u):$(id -g)" --tmpfs /tmp:rw,nosuid,nodev,size=512m,mode=1777 -v "$PWD/results:/results" forge-benchmark-local node benchmarks/v2/verify.cjs /results/my-run.json