Forge / Linux · 17–18 Oct 2026
Benchmarks
Gleiche Arbeit, gleicher Verkehr. Erkunden Sie die aufgezeichneten Messungen, verstehen Sie die Methode und wiederholen Sie jeden 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
Dasselbe Szenario vergleichen
RSS unter Last · MiB
Die Balken zeigen den Median aus drei Wiederholungen. Die Linien zeigen Minimum und Maximum. Der Speicher ist der RSS des Prozesses in MiB; jede Achse beginnt bei null. Die Reihenfolge der Frameworks ist fest, keine Rangliste.
| Framework | Ausgangs-RSS · MiB | RSS unter Last · MiB | RSS nach der Last · MiB | CPU · % | Latenz p99 · ms | Zielabdeckung · % | Gesunde Läufe |
|---|---|---|---|---|---|---|---|
| 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 | |||||||
Die Werte sind Median [Minimum–Maximum] über die Wiederholungen. Jeder RSS-Wert ist ein Median innerhalb der Phase; abgetastete Spitzen bleiben in den Rohdaten. Der Ausgangswert folgt auf die Bereitschaftsanfragen und ist daher kein Speicher völlig ohne Anfragen. Die CPU ist ein Prozentsatz einer logischen CPU im abgetasteten Fenster. p99 beschreibt abgeschlossene Anfragen; lesen Sie es zusammen mit den Fehlern und der Zielabdeckung.
Speicher während einer Messung
Ein frischer Prozess, jede Sekunde abgetastet. Die markierten Fenster zeigen Last und Erholung; Aufwärmen und Beruhigung gehen der Last voraus. Der RSS umfasst Runtime, Heap und nativen Speicher. Er ist nicht der aktive JavaScript-Heap.
Das Kit herunterladen und den Rechner vorbereiten
Nach der Vorbereitung des Testkits ausführen
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.jsonDer Befehl verwendet die eingefrorene Suite des gewählten Laufs. Gleichen Sie Hardware, Container-Limits und Hintergrundaktivität an, bevor Sie eine Wiederholung vergleichen. Prüfen Sie danach mit dem passenden v2/verify.cjs.
So lesen Sie das Ergebnis
Vergleichen Sie dieselbe Last bei derselben Zielrate und lesen Sie Latenz, CPU, Speicher, Fehler und Zielabdeckung gemeinsam. Auch die Runtime-Version spielt eine Rolle. Diese Messungen belegen nicht, dass ein Framework immer weniger Ressourcen verbraucht. Total.js 4 und 5 werden getrennt gezeigt; jedes nutzt seine aufgezeichnete Implementierung und Runtime.
Was gemessen wurde
Acht Adapter, vier Lasten und gemeinsame Ziele von 100 und 1.000 Anfragen/s: 192 Messungen. Jede Messung startet einen frischen Produktionsprozess: Antwortprüfung, 1,5 s Ausgangsphase, 15 s Aufwärmen, 6 s Beruhigung, 60 s Last und 30 s Erholung. Alle drei Wiederholungen werden aufbewahrt. Die Adapter wurden nacheinander gemessen. Die Inhalte erfolgreicher Antworten werden vor und nach der Last geprüft; der Generator fordert bis zu 32 Verbindungen an.
Total5 verwendet ein kompaktes NEWSCHEMA und einen direkten Controller zur JSON-Validierung; kleine JSON-Antworten liefert der Controller direkt. Der Vergleich enthält vollständige aufgezeichnete Szenarien, niemals das beste Zahlenergebnis. Meteor nutzt sein reines Server-Produktionsbundle; NestJS seinen Express-Adapter. Native Validatoren decken den gemessenen Inhalt ab; Ablehnung und Umwandlung können sich zwischen den Frameworks unterscheiden.
Umgebung
Gemeinsam genutzter Linux-x64-Host, Intel Core i7-6700. Jeder Messcontainer war auf 2 logische CPUs und 2 GiB begrenzt, ohne externes Netzwerk und ohne veröffentlichte Ports. Generator und simulierte Abhängigkeit teilten sich den Container. Node 24.14.1 wurde für Total4, Express, Fastify und Node http verwendet; Node 24.15.0 für Total5, Meteor, AdonisJS und NestJS, passend zur Runtime des Meteor-Bundles. Die Runtime-Versionen stehen neben jedem Framework: Unterschiede lassen sich nicht allein dem Framework zuschreiben. Produktionsdienste liefen weiter auf dem Host.
Was diese Ergebnisse nicht belegen
Dies ist ein Experiment mit fester Rate und geschlossener Schleife, keine Rangliste des maximalen Durchsatzes. Das Erreichen des Ziels belegt nicht, wie ein Adapter unabhängige Ankünfte oder Sättigung bewältigt. Es gab eine gewisse Drosselung durch die CPU-Quote, vermerkt in der Prüfung. Drei kurze Wiederholungen belegen weder Langzeitstabilität noch das Fehlen von Speicherlecks, Produktionssicherheit, das Verhalten von Flow oder den Speicherbedarf auf dem Raspberry Pi. Die Garbage Collection wurde nicht erzwungen. Der RSS kann nach dem Ende des Verkehrs belegt bleiben.
Eine Zelle ist gesund, wenn die abgeschlossenen Anfragen mindestens 95 % von Zielrate × Generatordauer erreichen, p99 höchstens 250 ms beträgt und die Zahl der Fehler, Timeouts und Nicht-2xx-Antworten null ist. Diese Schwelle behauptet keine gleiche Maximalkapazität.
Originalbelege
Vollständiger Framework-Vergleich
Prüfung von Integrität und Umgebung · SHA-256-Prüfsummen · JSON · Markdown
Nachstellen und prüfen
Verwenden Sie ein leeres Verzeichnis mit Docker (Linux-Container), curl und tar. Node.js wird auf dem Host nicht benötigt: Prüfsummenkontrolle und Testsuite nutzen Node 24.15.0 in Docker. Der erste Build lädt Abhängigkeiten herunter und kompiliert Meteor, was einige Minuten dauern kann. Die Vorbereitung braucht Internet; die Testcontainer haben kein externes Netzwerk. Jedes gemessene Szenario dauert etwa sechs Minuten.
Das Kit führt alle acht Adapter mit Node v24.15.0 aus. Die veröffentlichten Messungen behalten ihre ursprünglichen Runtimes, die in der Tabelle stehen.
Das vollständige Testkit herunterladen
1. Herunterladen und vorbereiten. Der Link enthält den Runner, die Adapter und die Abhängigkeits-Locks; weder eine Forge-Installation noch das Klonen eines Repositorys ist nötig. Führen Sie in einem leeren Verzeichnis die folgenden Befehle aus. Wenn Sie mit der Schaltfläche heruntergeladen haben, behalten Sie den Dateinamen sources.tar.gz und lassen curl weg.
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. Die Installation prüfen (etwa 15–30 Sekunden). Dieser kurze Test erzeugt smoke.json und prüft dessen aufgezeichnete Eingaben; er ist kein veröffentlichbares Leistungsergebnis.
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. Die gewählte Messung ausführen und prüfen. Die Ergebnisse werden in results/my-run.json im gewählten benchmarks-Verzeichnis gespeichert. Der Runner überschreibt keine vorhandene Ausgabe: Verwenden Sie für eine Wiederholung einen anderen Dateinamen. Die Prüfung kontrolliert Vollständigkeit und Eingaben, nicht die Gleichheit mit den veröffentlichten Werten.
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