# Benchmarks

Samma arbete, samma trafik. Utforska de dokumenterade mätningarna, förstå metoden och upprepa varje test.

## Vad som mättes

Åtta adaptrar, fyra belastningar och gemensamma mål på 100 och 1 000 begäranden/s: 192 mätningar. Varje mätning startar en ny produktionsprocess: svarskontroll, 1,5 s utgångsläge, 15 s uppvärmning, 6 s stabilisering, 60 s belastning och 30 s återhämtning. Alla tre upprepningarna behålls. Adaptrarna mättes en i taget. Innehållet i lyckade svar kontrolleras före och efter belastningen; generatorn begär upp till 32 anslutningar.

Total5 använder ett kompakt NEWSCHEMA och en direkt kontroller för JSON-validering; små JSON-svar returneras direkt av kontrollern. Jämförelsen innehåller kompletta dokumenterade scenarier, aldrig det bästa siffervärdet. Meteor använder sitt produktionsbundle enbart för servern; NestJS sin Express-adapter. Inbyggda validerare täcker det mätta innehållet; avvisning och konvertering kan skilja sig mellan ramverk.

## Miljö

Delad Linux x64-värd, Intel Core i7-6700. Varje mätcontainer var begränsad till 2 logiska CPU:er och 2 GiB, utan externt nätverk och publicerade portar. Generatorn och det simulerade beroendet delade container. Node 24.14.1 användes för Total4, Express, Fastify och Node http; Node 24.15.0 för Total5, Meteor, AdonisJS och NestJS, i linje med runtime för Meteor-bundlet. Runtime-versionerna visas bredvid varje ramverk: skillnader kan inte tillskrivas enbart ramverket. Produktionstjänster fortsatte köra på värden.

## Vad resultaten inte visar

Detta är ett experiment med fast takt och sluten slinga, inte en rangordning av maximal genomströmning. Att nå det konfigurerade målet visar inte hur en adapter hanterar oberoende ankomster eller mättnad. Viss CPU-strypning på grund av kvot förekom och noterades i granskningen. Tre korta upprepningar visar inte långsiktig stabilitet, frånvaro av minnesläckor, produktionssäkerhet, Flows beteende eller minnesanvändning på Raspberry Pi. Skräpinsamling tvingades inte. RSS kan förbli reserverat när trafiken har upphört.

En cell är frisk när de slutförda begärandena når minst 95 % av målet × generatorns varaktighet, p99 är högst 250 ms och antalet fel, timeouts och icke-2xx-svar är noll. Den här tröskeln påstår inte lika stor maximal kapacitet.

## Så läser du resultatet

Jämför samma belastning vid samma måltakt och läs latens, CPU, minne, fel och målets täckning tillsammans. Runtime-versionen spelar också roll. Mätningarna visar inte att ett ramverk alltid använder färre resurser. Total.js 4 och 5 visas separat; vart och ett använder sin dokumenterade implementation och runtime.

## Fullständig jämförelse av ramverk

Slutförd: 2026-10-18T13:56:39.143Z; Node v24.14.1 / v24.15.0 (see runtimeByFramework).

| Framework | Node | Workload | req/s | Healthy | RSS baseline MiB | RSS load MiB | RSS recovery MiB | CPU % | p99 ms |
|---|---|---|---:|---|---|---|---|---|---|
| Total.js 4 | v24.14.1 | hello | 100 | 3/3 | 61.2 [61.0–61.2] | 89.8 [87.0–90.7] | 91.0 [88.3–105.4] | 1.7 [1.7–1.7] | 5.0 [5.0–6.0] |
| Express | v24.14.1 | hello | 100 | 3/3 | 74.2 [74.1–74.3] | 90.7 [90.4–91.5] | 90.8 [90.3–91.5] | 1.9 [1.9–2.0] | 7.0 [6.0–7.0] |
| Fastify | v24.14.1 | hello | 100 | 3/3 | 76.0 [75.5–76.0] | 91.3 [91.0–91.9] | 91.4 [91.0–91.9] | 1.4 [1.4–1.4] | 5.0 [5.0–5.0] |
| Node.js http | v24.14.1 | hello | 100 | 3/3 | 50.2 [50.2–50.3] | 68.8 [66.6–69.2] | 69.2 [67.0–69.5] | 1.4 [1.4–1.4] | 5.0 [5.0–5.0] |
| Total.js 4 | v24.14.1 | catalog | 100 | 3/3 | 61.3 [61.1–62.1] | 104.6 [94.9–106.2] | 106.4 [105.1–108.6] | 2.1 [2.1–2.1] | 8.0 [8.0–8.0] |
| Express | v24.14.1 | catalog | 100 | 3/3 | 74.1 [74.0–74.1] | 92.0 [91.9–94.5] | 92.3 [91.9–94.5] | 2.3 [2.3–2.4] | 9.0 [9.0–9.0] |
| Fastify | v24.14.1 | catalog | 100 | 3/3 | 75.8 [75.2–75.8] | 93.2 [92.6–93.4] | 93.4 [93.1–93.5] | 1.9 [1.8–1.9] | 8.0 [7.0–8.0] |
| Node.js http | v24.14.1 | catalog | 100 | 3/3 | 50.2 [50.1–50.3] | 66.0 [65.9–68.4] | 66.3 [66.1–68.7] | 1.8 [1.8–1.8] | 6.0 [6.0–7.0] |
| Total.js 4 | v24.14.1 | validate | 100 | 3/3 | 61.4 [61.3–61.6] | 96.4 [95.4–100.2] | 100.8 [98.3–101.9] | 2.0 [2.0–2.2] | 7.0 [6.0–8.0] |
| Express | v24.14.1 | validate | 100 | 3/3 | 74.0 [74.0–75.0] | 98.5 [94.4–99.0] | 98.6 [94.4–99.3] | 2.3 [2.2–2.3] | 9.0 [8.0–9.0] |
| Fastify | v24.14.1 | validate | 100 | 3/3 | 75.7 [75.6–76.0] | 97.3 [96.6–98.0] | 97.7 [96.2–98.0] | 1.7 [1.6–1.7] | 6.0 [5.0–6.0] |
| Node.js http | v24.14.1 | validate | 100 | 3/3 | 50.3 [50.2–50.5] | 71.6 [71.4–72.2] | 71.8 [71.4–72.6] | 1.7 [1.7–1.7] | 6.0 [6.0–6.0] |
| Total.js 4 | v24.14.1 | upstream | 100 | 3/3 | 67.2 [66.8–67.9] | 167.8 [166.7–169.5] | 175.3 [169.6–176.7] | 5.7 [5.7–5.8] | 19.0 [19.0–19.0] |
| Express | v24.14.1 | upstream | 100 | 3/3 | 80.2 [79.8–80.2] | 171.3 [171.2–171.4] | 173.7 [172.9–173.7] | 6.0 [5.7–6.2] | 20.0 [19.0–20.0] |
| Fastify | v24.14.1 | upstream | 100 | 3/3 | 80.3 [80.1–80.7] | 165.9 [165.8–168.4] | 168.7 [168.3–173.1] | 5.6 [4.8–5.8] | 20.0 [19.0–20.0] |
| Node.js http | v24.14.1 | upstream | 100 | 3/3 | 60.8 [60.7–61.6] | 161.9 [158.4–172.1] | 164.2 [159.9–174.2] | 5.5 [5.2–5.5] | 18.0 [18.0–19.0] |
| Total.js 4 | v24.14.1 | hello | 1000 | 3/3 | 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] |
| Express | v24.14.1 | hello | 1000 | 3/3 | 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] |
| Fastify | v24.14.1 | hello | 1000 | 3/3 | 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] |
| Node.js http | v24.14.1 | hello | 1000 | 3/3 | 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] |
| Total.js 4 | v24.14.1 | catalog | 1000 | 3/3 | 61.2 [61.0–61.3] | 179.5 [179.5–180.0] | 179.9 [179.4–180.2] | 9.9 [9.9–9.9] | 13.0 [6.0–18.0] |
| Express | v24.14.1 | catalog | 1000 | 3/3 | 73.8 [73.7–74.0] | 91.8 [91.1–92.9] | 91.8 [91.3–92.9] | 9.5 [9.4–9.8] | 5.0 [5.0–11.0] |
| Fastify | v24.14.1 | catalog | 1000 | 3/3 | 75.7 [75.3–75.9] | 94.1 [93.8–94.2] | 94.1 [93.8–94.2] | 7.1 [7.1–7.1] | 5.0 [5.0–5.0] |
| Node.js http | v24.14.1 | catalog | 1000 | 3/3 | 50.2 [50.1–50.2] | 72.6 [71.2–72.9] | 72.6 [71.2–73.2] | 7.3 [7.2–7.4] | 5.0 [4.0–5.0] |
| Total.js 4 | v24.14.1 | validate | 1000 | 3/3 | 62.2 [61.6–62.5] | 171.9 [170.7–172.7] | 175.7 [175.3–176.6] | 9.7 [9.5–10.0] | 6.0 [6.0–6.0] |
| Express | v24.14.1 | validate | 1000 | 3/3 | 74.4 [74.2–74.6] | 98.8 [98.2–99.7] | 98.8 [98.2–99.7] | 8.9 [8.9–9.2] | 8.0 [6.0–21.0] |
| Fastify | v24.14.1 | validate | 1000 | 3/3 | 75.9 [75.7–76.4] | 98.1 [98.1–98.4] | 98.1 [98.1–98.5] | 6.3 [6.2–6.3] | 5.0 [4.0–12.0] |
| Node.js http | v24.14.1 | validate | 1000 | 3/3 | 50.2 [50.2–50.4] | 71.0 [70.4–72.6] | 74.9 [74.2–76.4] | 6.2 [6.0–6.3] | 4.0 [4.0–13.0] |
| Total.js 4 | v24.14.1 | upstream | 1000 | 3/3 | 67.8 [67.8–67.8] | 202.3 [201.4–204.1] | 203.0 [201.6–204.7] | 36.3 [34.7–36.6] | 16.0 [15.0–16.0] |
| Express | v24.14.1 | upstream | 1000 | 3/3 | 80.7 [79.7–80.9] | 178.7 [177.6–187.7] | 182.6 [181.9–190.4] | 35.0 [32.6–35.4] | 15.0 [15.0–16.0] |
| Fastify | v24.14.1 | upstream | 1000 | 3/3 | 79.3 [79.3–79.3] | 194.0 [179.4–194.6] | 194.0 [179.6–194.9] | 33.8 [27.7–34.2] | 15.0 [14.0–15.0] |
| Node.js http | v24.14.1 | upstream | 1000 | 3/3 | 60.9 [60.7–61.0] | 171.9 [171.8–174.6] | 178.0 [175.5–179.3] | 29.0 [23.6–30.5] | 14.0 [13.0–15.0] |
| Meteor | v24.15.0 | hello | 100 | 3/3 | 123.7 [123.5–124.7] | 130.2 [128.1–131.3] | 159.1 [151.6–160.9] | 3.5 [3.5–3.6] | 15.0 [14.0–19.0] |
| Meteor | v24.15.0 | catalog | 100 | 3/3 | 124.7 [123.3–124.8] | 138.9 [138.8–139.4] | 162.5 [157.0–162.7] | 3.9 [3.9–4.0] | 15.0 [14.0–16.0] |
| Meteor | v24.15.0 | validate | 100 | 3/3 | 124.4 [123.2–124.6] | 137.0 [134.6–138.8] | 163.4 [161.2–169.2] | 3.9 [3.8–3.9] | 18.0 [15.0–22.0] |
| Meteor | v24.15.0 | upstream | 100 | 3/3 | 126.5 [126.2–127.6] | 187.0 [181.6–188.3] | 188.9 [184.5–191.2] | 8.0 [7.7–8.1] | 25.0 [24.0–25.0] |
| Meteor | v24.15.0 | hello | 1000 | 3/3 | 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] |
| Meteor | v24.15.0 | catalog | 1000 | 3/3 | 124.1 [123.3–124.2] | 167.6 [167.6–172.5] | 168.0 [167.7–173.2] | 15.2 [15.1–15.9] | 10.0 [9.0–10.0] |
| Meteor | v24.15.0 | validate | 1000 | 3/3 | 125.2 [124.6–126.1] | 174.9 [173.8–175.0] | 176.3 [175.0–176.6] | 14.8 [14.6–14.9] | 10.0 [9.0–13.0] |
| Meteor | v24.15.0 | upstream | 1000 | 3/3 | 127.8 [127.2–128.3] | 213.9 [213.8–217.2] | 124.5 [122.1–126.7] | 38.2 [36.8–41.4] | 18.0 [17.0–19.0] |
| AdonisJS | v24.15.0 | hello | 100 | 3/3 | 114.9 [113.9–115.3] | 143.4 [143.0–149.2] | 144.3 [143.1–149.4] | 2.5 [2.3–2.5] | 9.0 [9.0–10.0] |
| AdonisJS | v24.15.0 | catalog | 100 | 3/3 | 114.4 [113.7–116.0] | 142.7 [142.7–142.9] | 143.6 [142.9–144.3] | 3.0 [3.0–3.1] | 13.0 [12.0–13.0] |
| AdonisJS | v24.15.0 | validate | 100 | 3/3 | 114.5 [114.3–115.0] | 147.0 [146.6–147.4] | 148.5 [148.1–148.5] | 3.0 [2.9–3.0] | 12.0 [12.0–13.0] |
| AdonisJS | v24.15.0 | upstream | 100 | 3/3 | 115.9 [112.8–116.2] | 195.2 [194.7–198.7] | 197.2 [194.8–199.7] | 6.3 [6.1–6.3] | 20.0 [20.0–21.0] |
| AdonisJS | v24.15.0 | hello | 1000 | 3/3 | 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] |
| AdonisJS | v24.15.0 | catalog | 1000 | 3/3 | 113.7 [113.2–114.4] | 149.3 [149.2–151.7] | 151.8 [151.7–153.0] | 14.5 [14.4–14.7] | 9.0 [8.0–9.0] |
| AdonisJS | v24.15.0 | validate | 1000 | 3/3 | 115.2 [115.1–115.7] | 149.4 [149.0–149.8] | 149.4 [148.9–149.5] | 13.7 [13.6–14.3] | 9.0 [7.0–10.0] |
| AdonisJS | v24.15.0 | upstream | 1000 | 3/3 | 115.0 [114.8–115.5] | 208.4 [203.9–221.8] | 212.1 [206.0–223.5] | 37.8 [35.6–38.7] | 15.0 [15.0–17.0] |
| NestJS · Express | v24.15.0 | hello | 100 | 3/3 | 99.8 [99.7–100.9] | 126.2 [125.2–130.1] | 126.4 [125.2–130.1] | 2.1 [2.1–2.2] | 7.0 [7.0–8.0] |
| NestJS · Express | v24.15.0 | catalog | 100 | 3/3 | 100.3 [99.8–100.4] | 127.1 [127.0–127.7] | 127.3 [127.0–127.8] | 2.5 [2.5–2.6] | 10.0 [10.0–10.0] |
| NestJS · Express | v24.15.0 | validate | 100 | 3/3 | 100.4 [100.3–101.0] | 130.0 [129.3–130.4] | 130.5 [130.5–130.9] | 2.4 [2.3–2.4] | 9.0 [8.0–13.0] |
| NestJS · Express | v24.15.0 | upstream | 100 | 3/3 | 102.4 [101.9–102.9] | 188.1 [183.4–189.5] | 190.1 [185.1–192.4] | 6.2 [6.1–6.2] | 20.0 [20.0–22.0] |
| NestJS · Express | v24.15.0 | hello | 1000 | 3/3 | 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] |
| NestJS · Express | v24.15.0 | catalog | 1000 | 3/3 | 100.8 [100.3–101.1] | 129.2 [127.9–132.9] | 129.4 [129.2–132.9] | 11.4 [11.3–11.5] | 11.0 [8.0–11.0] |
| NestJS · Express | v24.15.0 | validate | 1000 | 3/3 | 101.3 [101.2–101.4] | 132.2 [131.7–132.7] | 132.2 [131.7–132.7] | 10.7 [10.7–11.0] | 7.0 [6.0–8.0] |
| NestJS · Express | v24.15.0 | upstream | 1000 | 3/3 | 103.0 [101.1–103.4] | 201.2 [201.0–201.7] | 201.2 [201.1–201.7] | 37.1 [31.8–38.3] | 16.0 [16.0–17.0] |
| Total.js 5 | v24.15.0 | hello | 100 | 3/3 | 63.1 [63.0–63.2] | 94.6 [93.9–95.2] | 103.2 [103.1–104.0] | 1.6 [1.5–1.6] | 5.0 [5.0–6.0] |
| Total.js 5 | v24.15.0 | catalog | 100 | 3/3 | 63.3 [63.3–63.5] | 99.9 [99.9–100.7] | 107.5 [107.2–108.8] | 2.0 [1.9–2.1] | 7.0 [6.0–8.0] |
| Total.js 5 | v24.15.0 | validate | 100 | 3/3 | 63.2 [63.2–63.2] | 93.4 [92.2–94.2] | 96.7 [94.7–101.4] | 1.9 [1.8–2.0] | 7.0 [6.0–7.0] |
| Total.js 5 | v24.15.0 | upstream | 100 | 3/3 | 69.5 [69.4–69.5] | 168.3 [166.0–169.2] | 169.8 [167.4–172.5] | 5.6 [5.4–5.6] | 18.0 [18.0–18.0] |
| Total.js 5 | v24.15.0 | hello | 1000 | 3/3 | 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] |
| Total.js 5 | v24.15.0 | catalog | 1000 | 3/3 | 63.3 [63.3–63.5] | 175.0 [173.3–175.6] | 175.5 [173.7–181.0] | 9.9 [9.9–9.9] | 6.0 [5.0–9.0] |
| Total.js 5 | v24.15.0 | validate | 1000 | 3/3 | 63.2 [63.0–63.5] | 169.2 [164.2–169.4] | 171.4 [170.9–171.4] | 9.1 [9.0–9.2] | 22.0 [6.0–27.0] |
| Total.js 5 | v24.15.0 | upstream | 1000 | 3/3 | 68.4 [68.1–69.2] | 205.0 [203.3–206.0] | 207.9 [203.8–210.7] | 36.4 [30.2–36.8] | 23.0 [22.0–24.0] |

[Råa mätningar](/benchmarks/linux-20261017/general.json)

[Frysta källor och beroendelås](/benchmarks/linux-20261017/sources.tar.gz)

[Dokumenterad rapport](/benchmarks/linux-20261017/general-report.md)

[CSV per scenario](/benchmarks/linux-20261017/general.csv)

## Återskapa och granska

Använd en tom katalog med Docker (Linux-containrar), curl och tar. Node.js behövs inte på värden: både kontrollen av kontrollsumman och testsviten använder Node 24.15.0 i Docker. Det första bygget laddar ner beroenden och kompilerar Meteor, vilket kan ta flera minuter. Förberedelsen kräver internet; testcontainrarna har inget externt nätverk. Varje uppmätt scenario tar cirka sex minuter.

Hela satsen kör alla åtta adaptrar på Node 24.15.0 i Linux-containrar. Den innehåller körprogrammet, adaptrarna, beroendelåsen och bygganvisningarna för Meteor. De publicerade mätningarna behåller sina ursprungliga runtime-versioner och det ursprungliga källarkivet, tillgängliga under belägg; den här satsen förenhetligar bara nya körningar.

[Ladda ner hela testsatsen](https://forge.totaljs.es/benchmarks/node-24.15.0/sources.tar.gz)

1. Ladda ner och förbered. Länken innehåller körprogrammet, adaptrarna och beroendelåsen; ingen Forge-installation eller kloning av ett arkiv behövs. Kör följande kommandon i en tom katalog. Om du laddade ner med knappen, behåll filnamnet sources.tar.gz och hoppa över curl.

```bash
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. Kontrollera installationen (cirka 15–30 sekunder). Det korta testet skapar smoke.json och verifierar dess dokumenterade indata; det är inte ett publicerbart prestandaresultat.

```bash
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. Kör och verifiera den valda mätningen. Resultaten sparas i results/my-run.json i den valda benchmarks-katalogen. Körprogrammet vägrar skriva över befintlig utdata: använd ett annat filnamn vid en upprepning. Verifieringen kontrollerar fullständighet och indata, inte likhet med de publicerade siffrorna.

```bash
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
```

[JSON](/benchmarks/summary.json) · [Granskning av integritet och miljö](/benchmarks/linux-20261017/review.json) · [SHA-256](/benchmarks/linux-20261017/SHA256SUMS.txt)
