Forge
pt

Forge / Linux · 17–18 Oct 2026

Benchmarks

O mesmo trabalho, o mesmo tráfego. Explore as medições registadas, conheça o método e reproduza cada teste.

192Medições concluídas
3Repetições por cenário
0 / 0 / 0Erros, timeouts ou respostas falhadas
Node.js 24Kit: Node.js 24.15.0192 · Medições concluídasConcluída: 2026-10-18 13:56:39 UTC

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

Compare o mesmo cenário

RSS durante a carga · MiB

As barras mostram a mediana de três repetições. As linhas indicam o mínimo e o máximo. A memória é o RSS do processo em MiB; todos os eixos começam em zero. A ordem dos frameworks é fixa, não é uma classificação.

RSS durante a carga · MiB0.047.995.8143.7191.6Total.js 4: 159.3 [150.1–167.0]Total.js 4159.3Total.js 5: 165.7 [164.9–166.7]Total.js 5165.7Express: 90.8 [90.4–91.5]Express90.8Fastify: 91.2 [91.0–91.6]Fastify91.2Node.js http: 67.9 [67.5–69.8]Node.js http67.9Meteor: 168.6 [167.6–171.1]Meteor168.6AdonisJS: 145.3 [144.6–149.7]AdonisJS145.3NestJS · Express: 129.6 [129.4–130.0]NestJS · Express129.6
Todas as métricas deste cenário
FrameworkRSS inicial · MiBRSS em carga · MiBRSS após a carga · MiBCPU · %Latência p99 · msCobertura do objetivo · %Execuções saudáveis
Total.js 461.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 562.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
Express74.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
Fastify75.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 http50.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
Meteor124.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
AdonisJS114.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 · Express100.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.js
Total.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

Os valores são a mediana [mínimo–máximo] das repetições. Cada valor de RSS é uma mediana dentro da fase; os picos amostrados ficam nos dados originais. O valor inicial segue os pedidos de disponibilidade, por isso não é memória sem pedidos prévios. A CPU é uma percentagem de uma CPU lógica durante a janela amostrada. O p99 descreve os pedidos concluídos; leia-o em conjunto com os erros e a cobertura do objetivo.

A memória durante uma medição

Um processo novo, amostrado a cada segundo. As janelas sombreadas identificam a carga e a recuperação; o aquecimento e a estabilização antecedem a carga. O RSS inclui runtime, heap e memória nativa. Não é o heap de JavaScript em uso.

A memória durante uma medição · Total.js 5 · 10501001502000 s23 s45 s68 s90 s113 sMiB
RSSJS heapCargaRecuperação

Descarregar o kit e preparar o seu computador

Executar depois de preparar o kit de testes

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

O comando usa a suite congelada da execução escolhida. Iguale o hardware, os limites dos contentores e a atividade em segundo plano antes de comparar uma nova execução. Verifique depois com o v2/verify.cjs correspondente.

Como interpretar o resultado

Compare a mesma carga ao mesmo ritmo-alvo e leia em conjunto latência, CPU, memória, erros e cobertura do objetivo. A versão do runtime também importa. Estas medições não demonstram que um framework consuma sempre menos recursos. O Total.js 4 e o 5 aparecem separados; cada um usa a sua implementação e o seu runtime registados.

O que foi medido

Oito adaptadores, quatro cargas e objetivos comuns de 100 e 1.000 pedidos/s: 192 medições. Cada medição inicia um processo de produção novo: verificação da resposta, 1,5 s de base, 15 s de aquecimento, 6 s de estabilização, 60 s de carga e 30 s de recuperação. As três repetições são conservadas. Os adaptadores foram medidos em sequência. O conteúdo das respostas bem-sucedidas é verificado antes e depois da carga; o gerador pede até 32 ligações.

O Total5 usa um NEWSCHEMA compacto e um controlador direto para validar JSON; as respostas JSON pequenas são devolvidas diretamente pelo controlador. A comparação contém cenários completos registados, nunca o melhor resultado numérico. O Meteor usa o seu bundle de produção apenas de servidor; o NestJS usa o seu adaptador Express. Os validadores nativos cobrem o conteúdo medido; a rejeição e a conversão podem diferir entre frameworks.

Ambiente

Servidor Linux x64 partilhado, Intel Core i7-6700. Cada contentor de medição estava limitado a 2 CPU lógicas e 2 GiB, sem rede externa nem portas publicadas. O gerador e a dependência simulada partilhavam o contentor. O Node 24.14.1 foi usado para Total4, Express, Fastify e Node http; o Node 24.15.0 para Total5, Meteor, AdonisJS e NestJS, de acordo com o runtime do bundle do Meteor. As versões do runtime aparecem junto a cada framework: as diferenças não se podem atribuir apenas ao framework. Os serviços de produção continuaram no servidor.

O que estes resultados não demonstram

É uma experiência com ritmo fixo e ciclo fechado, não uma classificação de capacidade máxima. Atingir o objetivo configurado não demonstra como um adaptador lida com chegadas independentes ou saturação. Houve alguma limitação da CPU por quota, registada na revisão. Três repetições curtas não demonstram estabilidade a longo prazo, ausência de fugas de memória, segurança em produção, comportamento do Flow nem uso de memória no Raspberry Pi. Não se forçou a recolha de lixo. O RSS pode continuar reservado depois de o tráfego parar.

Uma célula é saudável quando os pedidos concluídos atingem pelo menos 95 % do objetivo × a duração do gerador, o p99 não excede 250 ms e as contagens de erros, timeouts e respostas não 2xx são zero. Este limiar não afirma uma capacidade máxima igual.

Evidências originais

Revisão de integridade e ambiente · Somas SHA-256 · JSON · Markdown

Reproduzir e verificar

Use uma pasta vazia com Docker (contentores Linux), curl e tar. Não precisa do Node.js no computador: a verificação da soma de controlo e a bateria de testes usam o Node 24.15.0 dentro do Docker. A primeira construção descarrega dependências e compila o Meteor, o que pode demorar vários minutos. A preparação precisa de internet; os contentores de teste não têm rede externa. Cada cenário medido demora cerca de seis minutos.

O kit executa os oito adaptadores com Node v24.15.0. As medições publicadas conservam os seus runtimes originais, indicados na tabela.

Descarregar o kit de testes completo

1. Descarregar e preparar. A ligação inclui o executor, os adaptadores e os bloqueios de dependências; não é preciso instalar o Forge nem clonar um repositório. Numa pasta vazia, execute os comandos seguintes. Se descarregou com o botão, mantenha o nome sources.tar.gz e ignore o 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. Verificar a instalação (cerca de 15–30 segundos). Este teste breve gera smoke.json e verifica as suas entradas registadas; não é um resultado de desempenho publicável.

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. Executar e verificar a medição escolhida. Os resultados são guardados em results/my-run.json dentro da pasta benchmarks selecionada. O executor recusa-se a substituir uma saída existente: use outro nome de ficheiro para repetir. A verificação controla a integridade e as entradas, não a igualdade com os valores publicados.

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