Forge
pl

Forge / Linux · 17–18 Oct 2026

Benchmarks

Ta sama praca, ten sam ruch. Poznaj zapisane pomiary, zrozum metodę i powtórz każdy test.

192Zakończone pomiary
3Powtórzenia na scenariusz
0 / 0 / 0Błędy, przekroczenia czasu lub nieudane odpowiedzi
Node.js 24Kit: Node.js 24.15.0192 · Zakończone pomiaryZakończono: 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

Porównaj ten sam scenariusz

RSS podczas obciążenia · MiB

Słupki pokazują medianę z trzech powtórzeń. Wąsy pokazują ich minimum i maksimum. Pamięć to RSS procesu w MiB; każda oś zaczyna się od zera. Kolejność frameworków jest stała i nie jest rankingiem.

RSS podczas obciążenia · 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
Wszystkie metryki tego scenariusza
FrameworkRSS początkowy · MiBRSS pod obciążeniem · MiBRSS po obciążeniu · MiBCPU · %Opóźnienie p99 · msPokrycie celu · %Zdrowe przebiegi
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

Wartości to mediana [minimum–maksimum] z powtórzeń. Każda wartość RSS jest medianą w obrębie fazy; próbkowane szczyty pozostają w danych surowych. Wartość początkowa następuje po żądaniach gotowości, więc nie jest pamięcią bez żadnych żądań. CPU to procent jednego logicznego CPU w próbkowanym oknie. p99 opisuje zakończone żądania; czytaj je razem z błędami i pokryciem celu.

Pamięć podczas jednego pomiaru

Jeden nowy proces, próbkowany co sekundę. Zacienione okna oznaczają obciążenie i powrót do normy; przed obciążeniem następuje rozgrzewka i ustabilizowanie. RSS obejmuje runtime, stertę i pamięć natywną. To nie jest aktywna sterta JavaScript.

Pamięć podczas jednego pomiaru · Total.js 5 · 10501001502000 s23 s45 s68 s90 s113 sMiB
RSSJS heapObciążeniePowrót do normy

Pobierz zestaw i przygotuj komputer

Uruchom po przygotowaniu zestawu testowego

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

Polecenie używa zamrożonego zestawu wybranego przebiegu. Ujednolić sprzęt, limity kontenerów i aktywność w tle przed porównaniem ponownego uruchomienia. Po zakończeniu zweryfikuj odpowiednim v2/verify.cjs.

Jak czytać wynik

Porównuj to samo obciążenie przy tym samym tempie docelowym i czytaj razem opóźnienie, CPU, pamięć, błędy i pokrycie celu. Ważna jest też wersja runtime. Te pomiary nie dowodzą, że jeden framework zawsze zużywa mniej zasobów. Total.js 4 i 5 pokazano osobno; każdy używa zapisanej implementacji i runtime.

Co zmierzono

Osiem adapterów, cztery obciążenia i wspólne cele 100 i 1000 żądań/s: 192 pomiary. Każdy pomiar uruchamia nowy proces produkcyjny: sprawdzenie odpowiedzi, 1,5 s bazy, 15 s rozgrzewki, 6 s ustabilizowania, 60 s obciążenia i 30 s powrotu do normy. Zachowano wszystkie trzy powtórzenia. Adaptery mierzono kolejno. Treść udanych odpowiedzi jest sprawdzana przed obciążeniem i po nim; generator żąda do 32 połączeń.

Total5 używa kompaktowego NEWSCHEMA i bezpośredniego kontrolera do walidacji JSON; małe odpowiedzi JSON zwraca bezpośrednio kontroler. Porównanie zawiera pełne zapisane scenariusze, nigdy najlepszy wynik liczbowy. Meteor używa swojego produkcyjnego bundla tylko serwerowego; NestJS używa adaptera Express. Natywne walidatory obejmują mierzoną treść; odrzucanie i konwersje mogą się różnić między frameworkami.

Środowisko

Współdzielony host Linux x64, Intel Core i7-6700. Każdy kontener pomiarowy był ograniczony do 2 logicznych CPU i 2 GiB, bez sieci zewnętrznej i opublikowanych portów. Generator i symulowana zależność dzieliły kontener. Node 24.14.1 użyto dla Total4, Express, Fastify i Node http; Node 24.15.0 dla Total5, Meteor, AdonisJS i NestJS, zgodnie z runtime bundla Meteor. Wersje runtime są pokazane przy każdym frameworku: różnic nie można przypisać samemu frameworkowi. Usługi produkcyjne pozostały na hoście.

Czego te wyniki nie dowodzą

To eksperyment ze stałym tempem i zamkniętą pętlą, a nie ranking maksymalnej przepustowości. Osiągnięcie ustawionego celu nie dowodzi, jak adapter radzi sobie z niezależnymi nadejściami czy nasyceniem. Wystąpiło pewne ograniczanie CPU przez limit, odnotowane w przeglądzie. Trzy krótkie powtórzenia nie dowodzą długoterminowej stabilności, braku wycieków pamięci, bezpieczeństwa produkcyjnego, zachowania Flow ani użycia pamięci na Raspberry Pi. Nie wymuszano odśmiecania pamięci. RSS może pozostać zajęte po ustaniu ruchu.

Komórka jest zdrowa, gdy zakończone żądania osiągają co najmniej 95% celu × czas pracy generatora, p99 nie przekracza 250 ms, a liczby błędów, przekroczeń czasu i odpowiedzi innych niż 2xx wynoszą zero. Ten próg nie twierdzi, że wszystkie mają równą maksymalną pojemność.

Oryginalne dowody

Przegląd integralności i środowiska · Sumy kontrolne SHA-256 · JSON · Markdown

Odtwórz i sprawdź

Użyj pustego katalogu z Dockerem (kontenery Linux), curl i tar. Node.js nie jest potrzebny na hoście: sprawdzenie sumy kontrolnej i zestaw testów używają Node 24.15.0 w Dockerze. Pierwsze budowanie pobiera zależności i kompiluje Meteor, co może potrwać kilka minut. Przygotowanie wymaga internetu; kontenery testowe nie mają sieci zewnętrznej. Każdy mierzony scenariusz trwa około sześciu minut.

Zestaw uruchamia wszystkie osiem adapterów na Node v24.15.0. Opublikowane pomiary zachowują oryginalne runtime, pokazane w tabeli.

Pobierz pełny zestaw testowy

1. Pobierz i przygotuj. Odnośnik zawiera program uruchamiający, adaptery i blokady zależności; nie trzeba instalować Forge ani klonować repozytorium. W pustym katalogu uruchom poniższe polecenia. Jeśli pobrano przyciskiem, zachowaj nazwę sources.tar.gz i pomiń 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. Sprawdź instalację (około 15–30 sekund). Ten krótki test tworzy smoke.json i weryfikuje jego zapisane dane wejściowe; nie jest to wynik wydajności do publikacji.

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. Uruchom i zweryfikuj wybrany pomiar. Wyniki są zapisywane w results/my-run.json w wybranym katalogu benchmarks. Program odmawia nadpisania istniejącego wyniku: do powtórzenia użyj innej nazwy pliku. Weryfikacja sprawdza kompletność i dane wejściowe, nie zgodność z opublikowanymi liczbami.

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