Forge
ro

Forge / Linux · 17–18 Oct 2026

Benchmarks

Aceeași muncă, același trafic. Explorează măsurătorile înregistrate, înțelege metoda și reproduce fiecare test.

192Măsurători finalizate
3Repetări pe scenariu
0 / 0 / 0Erori, depășiri de timp sau răspunsuri eșuate
Node.js 24Kit: Node.js 24.15.0192 · Măsurători finalizateFinalizat: 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

Compară același scenariu

RSS în timpul sarcinii · MiB

Barele arată mediana a trei repetări. Liniile arată minimul și maximul. Memoria este RSS-ul procesului în MiB; fiecare axă pornește de la zero. Ordinea framework-urilor este fixă, nu este un clasament.

RSS în timpul sarcinii · 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
Toate metricile acestui scenariu
FrameworkRSS inițial · MiBRSS sub sarcină · MiBRSS după sarcină · MiBCPU · %Latență p99 · msAcoperirea țintei · %Rulări sănătoase
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

Valorile sunt mediana [minim–maxim] a repetărilor. Fiecare valoare RSS este o mediană în cadrul fazei; vârfurile eșantionate rămân în datele brute. Valoarea inițială urmează cererilor de disponibilitate, deci nu este memorie fără nicio cerere. CPU este un procent dintr-un CPU logic în fereastra eșantionată. p99 descrie cererile finalizate; citește-l împreună cu erorile și acoperirea țintei.

Memoria în timpul unei măsurători

Un proces nou, eșantionat în fiecare secundă. Ferestrele umbrite arată sarcina și recuperarea; încălzirea și stabilizarea preced sarcina. RSS include runtime-ul, heap-ul și memoria nativă. Nu este heap-ul JavaScript activ.

Memoria în timpul unei măsurători · Total.js 5 · 10501001502000 s23 s45 s68 s90 s113 sMiB
RSSJS heapSarcinăRecuperare

Descarcă kitul și pregătește calculatorul

De rulat după pregătirea kitului de testare

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

Comanda folosește suita înghețată a rulării alese. Aliniază hardware-ul, limitele containerelor și activitatea de fundal înainte de a compara o nouă rulare. Verifică apoi cu v2/verify.cjs corespunzător.

Cum citești rezultatul

Compară aceeași sarcină la același ritm țintă și citește împreună latența, CPU, memoria, erorile și acoperirea țintei. Contează și versiunea runtime. Aceste măsurători nu demonstrează că un framework consumă întotdeauna mai puține resurse. Total.js 4 și 5 sunt arătate separat; fiecare folosește implementarea și runtime-ul înregistrate.

Ce s-a măsurat

Opt adaptoare, patru sarcini și ținte comune de 100 și 1.000 de cereri/s: 192 de măsurători. Fiecare măsurătoare pornește un proces de producție nou: verificarea răspunsului, 1,5 s de bază, 15 s de încălzire, 6 s de stabilizare, 60 s de sarcină și 30 s de recuperare. Sunt păstrate toate cele trei repetări. Adaptoarele au fost măsurate pe rând. Conținutul răspunsurilor reușite este verificat înainte și după sarcină; generatorul cere până la 32 de conexiuni.

Total5 folosește un NEWSCHEMA compact și un controller direct pentru validarea JSON; răspunsurile JSON mici sunt returnate direct de controller. Comparația conține scenarii complete înregistrate, niciodată cel mai bun rezultat numeric. Meteor folosește bundle-ul său de producție doar pentru server; NestJS adaptorul său Express. Validatoarele native acoperă conținutul măsurat; respingerea și conversiile pot diferi între framework-uri.

Mediu

Gazdă Linux x64 partajată, Intel Core i7-6700. Fiecare container de măsurare era limitat la 2 CPU logice și 2 GiB, fără rețea externă și fără porturi publicate. Generatorul și dependența simulată împărțeau containerul. Node 24.14.1 a fost folosit pentru Total4, Express, Fastify și Node http; Node 24.15.0 pentru Total5, Meteor, AdonisJS și NestJS, în acord cu runtime-ul bundle-ului Meteor. Versiunile runtime sunt arătate lângă fiecare framework: diferențele nu pot fi atribuite doar framework-ului. Serviciile de producție au rămas pe gazdă.

Ce nu demonstrează aceste rezultate

Este un experiment cu ritm fix și buclă închisă, nu un clasament al capacității maxime. Atingerea țintei configurate nu demonstrează cum tratează un adaptor sosirile independente sau saturarea. A existat o anumită limitare a CPU prin cotă, înregistrată în revizuire. Trei repetări scurte nu demonstrează stabilitate pe termen lung, absența scurgerilor de memorie, securitate în producție, comportamentul Flow sau consumul de memorie pe Raspberry Pi. Colectarea de gunoi nu a fost forțată. RSS poate rămâne alocat după oprirea traficului.

O celulă este sănătoasă când cererile finalizate ating cel puțin 95% din ținta × durata generatorului, p99 nu depășește 250 ms, iar numărul de erori, depășiri de timp și răspunsuri non-2xx este zero. Acest prag nu afirmă o capacitate maximă egală.

Dovezi originale

Revizuirea integrității și a mediului · Sume de control SHA-256 · JSON · Markdown

Reproducere și verificare

Folosește un director gol cu Docker (containere Linux), curl și tar. Node.js nu este necesar pe gazdă: verificarea sumei de control și suita de teste folosesc Node 24.15.0 în Docker. Prima construire descarcă dependențe și compilează Meteor, ceea ce poate dura câteva minute. Pregătirea necesită internet; containerele de test nu au rețea externă. Fiecare scenariu măsurat durează aproximativ șase minute.

Kitul rulează toate cele opt adaptoare pe Node v24.15.0. Măsurătorile publicate își păstrează runtime-urile originale, arătate în tabel.

Descarcă kitul complet de testare

1. Descarcă și pregătește. Linkul conține executorul, adaptoarele și blocările de dependențe; nu e nevoie să instalezi Forge sau să clonezi un depozit. Într-un director gol, rulează comenzile următoare. Dacă ai descărcat cu butonul, păstrează numele sources.tar.gz și sari peste 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. Verifică instalarea (aproximativ 15–30 de secunde). Acest test scurt produce smoke.json și îi verifică intrările înregistrate; nu este un rezultat de performanță publicabil.

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. Rulează și verifică măsurătoarea aleasă. Rezultatele sunt salvate în results/my-run.json în directorul benchmarks selectat. Executorul refuză să suprascrie o ieșire existentă: folosește alt nume de fișier pentru o repetare. Verificarea controlează completitudinea și intrările, nu egalitatea cu cifrele publicate.

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