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.
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.
| Framework | RSS inițial · MiB | RSS sub sarcină · MiB | RSS după sarcină · MiB | CPU · % | Latență p99 · ms | Acoperirea țintei · % | Rulări sănătoase |
|---|---|---|---|---|---|---|---|
| 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 | |||||||
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.
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.jsonComanda 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
Comparație completă a framework-urilor
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