diff --git a/frameworks/fulmine/README.md b/frameworks/fulmine/README.md index e8f79a0a79..b7078f5279 100644 --- a/frameworks/fulmine/README.md +++ b/frameworks/fulmine/README.md @@ -43,3 +43,8 @@ and why they are there are in the framework's - `tls_check`: the listener on :9000 reads `/certs-tls`, and a rotation is a new listener on the shared port followed by `close()` on the old one, since uWS reads the pair only when it builds the SSL context. +- HTTP/2 (`baseline-h2`, `static-h2` on :8443, `baseline-h2c`, `json-h2c` on :8082): uWS has no + HTTP/2, so the same app is handed to `node:http2` with its defaults, one socket per worker with + `SO_REUSEPORT`: [node:http2](https://fulmine.sndesign.it/examples/node-http#http-2). +- `/json` on the TLS listener has no `compression()`: json-tls never sends `Accept-Encoding`. + The production-stack item cache lives one second, the profile's limit. diff --git a/frameworks/fulmine/app.js b/frameworks/fulmine/app.js index 058fa4c443..79f9dae2a9 100644 --- a/frameworks/fulmine/app.js +++ b/frameworks/fulmine/app.js @@ -85,7 +85,8 @@ app.get('/delay/:ms', (req, res) => { setTimeout(() => res.type('text/plain').send(String(ms)), ms); }); -const registerJsonRoute = (target, path = '/json/:count') => target.get(path, compress, (req, res) => { +// json-tls never sends Accept-Encoding, so the TLS listener registers it without compress. +const registerJsonRoute = (target, path = '/json/:count', ...before) => target.get(path, ...before, (req, res) => { const count = Math.min(Math.max(parseInt(req.params.count, 10) || 0, 0), dataset.length); const m = parseInt(req.query.m, 10) || 1; const items = new Array(count); @@ -114,7 +115,7 @@ const registerStaticRoute = (target) => target.use('/static', express.static('/d fallthrough: false })); -registerJsonRoute(app); +registerJsonRoute(app, '/json/:count', compress); registerEchoRoute(app); registerStaticRoute(app); @@ -163,7 +164,7 @@ app.get('/fortunes', async (req, res) => { app.get('/public/baseline', (req, res) => { res.type('text/plain').send(String(sumQuery(req.query))); }); - registerJsonRoute(app, '/public/json/:count'); + registerJsonRoute(app, '/public/json/:count', compress); app.get('/api/items/:id', async (req, res) => { const id = parseInt(req.params.id, 10); @@ -177,7 +178,8 @@ app.get('/fortunes', async (req, res) => { }); if (rows.length === 0) return res.status(404).end(); const json = JSON.stringify(itemShape(rows[0])); - cache().set('crud:' + id, json, 'PX', 200); + // the profile allows a TTL up to one second + cache().set('crud:' + id, json, 'PX', 1000); res.set(CACHE_MISS).type('application/json').send(json); }); @@ -238,6 +240,19 @@ const hasPair = (dir) => fs.existsSync(dir + '/server.key') && fs.existsSync(dir if (hasPair('/certs')) tlsApp('/certs').listen(8081); +// HTTP/2: µWS has none, so the same app goes to node:http2 with its defaults, h2 with TLS on 8443 +// and h2c on 8082. Every worker binds its own socket with SO_REUSEPORT, as the uWS listeners do. +// https://fulmine.sndesign.it/examples/node-http#http-2 +if (require('cluster').isWorker) { + const http2 = require('http2'); + const own = { reusePort: true, exclusive: true }; + http2.createServer(app).listen({ port: 8082, ...own }); + if (hasPair('/certs')) { + const pair = { key: fs.readFileSync('/certs/server.key'), cert: fs.readFileSync('/certs/server.crt') }; + http2.createSecureServer(pair, app).listen({ port: 8443, ...own }); + } +} + // tls_check, mounted only by validate.sh. uWS reads the pair once per SSL context, so a rotation // is a new listener on the shared port, then close() on the old one, which drains it. if (hasPair('/certs-tls')) { diff --git a/frameworks/fulmine/compose.gateway-h3.yml b/frameworks/fulmine/compose.gateway-h3.yml index 7896b56ab1..90dace7ff7 100644 --- a/frameworks/fulmine/compose.gateway-h3.yml +++ b/frameworks/fulmine/compose.gateway-h3.yml @@ -1,11 +1,10 @@ # gateway-h3 - the same two services as compose.gateway.yml, reached over QUIC -# instead. Stock Caddy already binds 8443 on tcp and udp with `protocols h1 h2 -# h3`, so the proxy config is identical and only the load generator differs. -# The proxy to server hop stays loopback h1 either way. +# instead. Stock nginx with http3 on udp 8443, the same edge as ./proxy-nginx +# plus the quic listen. The proxy to server hop stays loopback h1. services: proxy: build: - context: ./proxy + context: ./proxy-h3 network_mode: host cpuset: "${PROXY_CPUSET:-0-15,64-79}" ulimits: diff --git a/frameworks/fulmine/compose.gateway.yml b/frameworks/fulmine/compose.gateway.yml index 87911dd22f..85d8f1964e 100644 --- a/frameworks/fulmine/compose.gateway.yml +++ b/frameworks/fulmine/compose.gateway.yml @@ -1,7 +1,6 @@ # gateway-64 - stock nginx (TLS + h2 on 8443) in front of the fulmine server, # forwarding the dynamic endpoints over loopback h1 with keepalive. The server -# gets no certs here, so it comes up cleartext on 8080 only. Caddy stays on -# the h3 profile only: here the edge is what saturates, and the Caddy one +# gets no certs here, so it comes up cleartext on 8080 only. The Caddy edge # topped out near a third of what nginx moves on the same split. # # The CPU split is the knob worth sweeping, via PROXY_CPUSET / SERVER_CPUSET. diff --git a/frameworks/fulmine/meta.json b/frameworks/fulmine/meta.json index 020d88424b..89eea78fe8 100644 --- a/frameworks/fulmine/meta.json +++ b/frameworks/fulmine/meta.json @@ -31,7 +31,11 @@ "gateway-64", "gateway-h3", "production-stack", - "fortunes" + "fortunes", + "baseline-h2", + "static-h2", + "baseline-h2c", + "json-h2c" ], "maintainers": [ "nigrosimone" diff --git a/frameworks/fulmine/package.json b/frameworks/fulmine/package.json index 6e2bf187aa..23112a26ff 100644 --- a/frameworks/fulmine/package.json +++ b/frameworks/fulmine/package.json @@ -2,7 +2,7 @@ "name": "httparena-fulmine", "private": true, "dependencies": { - "fulmine.js": "^5.25.10", + "fulmine.js": "^5.26.0", "pg": "^8.13.0", "pg-native": "^3.8.0", "ejs": "^3.1.10", diff --git a/frameworks/fulmine/proxy-h3/Dockerfile b/frameworks/fulmine/proxy-h3/Dockerfile new file mode 100644 index 0000000000..f1ab6bd304 --- /dev/null +++ b/frameworks/fulmine/proxy-h3/Dockerfile @@ -0,0 +1,11 @@ +# Stock nginx, its official build has http_v3_module. Same edge as ../proxy-nginx, with QUIC. +FROM nginx:1.27-alpine + +COPY nginx.conf /etc/nginx/nginx.conf +# run by the image's entrypoint before nginx starts +COPY workers.sh /docker-entrypoint.d/30-workers.sh +RUN chmod +x /docker-entrypoint.d/30-workers.sh + +EXPOSE 8443/tcp 8443/udp + +CMD ["nginx", "-g", "daemon off;"] diff --git a/frameworks/fulmine/proxy-h3/nginx.conf b/frameworks/fulmine/proxy-h3/nginx.conf new file mode 100644 index 0000000000..ac5e174432 --- /dev/null +++ b/frameworks/fulmine/proxy-h3/nginx.conf @@ -0,0 +1,74 @@ +# fulmine gateway-h3 edge, nginx. +# +# nginx terminates QUIC and h3 on udp 8443 (TLS and h2 on tcp 8443), serves /static/* from disk and +# forwards the rest to the fulmine server over loopback h1 through a keepalive pool. Caddy was here +# before: every entry behind it lands at 56-63k at 256 connections, whatever the backend. + +# set to the cpuset size by workers.sh +worker_processes 1; +worker_rlimit_nofile 1048576; + +events { + worker_connections 65535; + multi_accept on; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + + # precompressed .gz sidecars straight from disk, nothing is compressed per request + gzip_static on; + gzip_vary on; + + keepalive_timeout 300s; + # the generator holds its connections for the whole run, so never close one on a request count + keepalive_requests 1000000; + + access_log off; + error_log /dev/stderr warn; + + upstream backend { + server 127.0.0.1:8080; + keepalive 2048; + keepalive_requests 1000000; + keepalive_timeout 300s; + } + + server { + # reuseport: one QUIC socket per worker, so the kernel spreads the connections + listen 8443 quic reuseport; + # Loopback, not the wildcard: validate.sh keeps the standalone container up beside the stack, + # and its h2 server holds *:8443 with SO_REUSEPORT. A specific address wins the lookup, the + # same fix as anole, plod and libuvcpp. + listen 127.0.0.1:8443 ssl backlog=65535 reuseport; + listen [::1]:8443 ssl backlog=65535 reuseport; + http2 on; + http3 on; + add_header Alt-Svc 'h3=":8443"; ma=86400' always; + + ssl_certificate /certs/server.crt; + ssl_certificate_key /certs/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers off; + + # the profile asks the proxy to serve these from disk rather than forward them + location /static/ { + alias /data/static/; + expires off; + add_header Cache-Control "no-cache"; + } + + # everything else is the fulmine server + location / { + proxy_pass http://backend; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Host $host; + } + } +} diff --git a/frameworks/fulmine/proxy-h3/workers.sh b/frameworks/fulmine/proxy-h3/workers.sh new file mode 100755 index 0000000000..422c16a3f8 --- /dev/null +++ b/frameworks/fulmine/proxy-h3/workers.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# One nginx worker per CPU of the container's cpuset: nproc honours it, `auto` may count the host. +sed -i "s/^worker_processes .*/worker_processes $(nproc);/" /etc/nginx/nginx.conf diff --git a/frameworks/fulmine/proxy-nginx/nginx.conf b/frameworks/fulmine/proxy-nginx/nginx.conf index d12901a10d..61aae304f5 100644 --- a/frameworks/fulmine/proxy-nginx/nginx.conf +++ b/frameworks/fulmine/proxy-nginx/nginx.conf @@ -1,9 +1,8 @@ # fulmine gateway edge, nginx. # # nginx terminates TLS and h2 on 8443, serves /static/* from disk and forwards the rest to the -# fulmine server over loopback h1 through a keepalive pool. gateway-h3 keeps the Caddy edge in -# ./proxy: nginx does QUIC too, but on that profile every edge measures about the same, and on -# this one the edge is what saturates, so it is the one worth changing. +# fulmine server over loopback h1 through a keepalive pool. gateway-h3 uses the same edge with +# QUIC, in ../proxy-h3. worker_processes auto; worker_rlimit_nofile 1048576; @@ -40,7 +39,11 @@ http { } server { - listen 8443 ssl; + # Loopback, not the wildcard: validate.sh keeps the standalone container up beside the stack, + # and its h2 server holds *:8443 with SO_REUSEPORT. A specific address wins the lookup, the + # same fix as anole, plod and libuvcpp. reuseport is needed to bind beside that socket. + listen 127.0.0.1:8443 ssl reuseport; + listen [::1]:8443 ssl reuseport; http2 on; ssl_certificate /certs/server.crt; diff --git a/frameworks/fulmine/proxy-production/nginx.conf b/frameworks/fulmine/proxy-production/nginx.conf index c6cd732843..44edc31c86 100644 --- a/frameworks/fulmine/proxy-production/nginx.conf +++ b/frameworks/fulmine/proxy-production/nginx.conf @@ -45,7 +45,11 @@ http { } server { - listen 8443 ssl; + # Loopback, not the wildcard: validate.sh keeps the standalone container up beside the stack, + # and its h2 server holds *:8443 with SO_REUSEPORT. A specific address wins the lookup, the + # same fix as anole, plod and libuvcpp. reuseport is needed to bind beside that socket. + listen 127.0.0.1:8443 ssl reuseport; + listen [::1]:8443 ssl reuseport; http2 on; ssl_certificate /certs/server.crt; diff --git a/frameworks/fulmine/proxy/Caddyfile b/frameworks/fulmine/proxy/Caddyfile deleted file mode 100644 index 330c51ed35..0000000000 --- a/frameworks/fulmine/proxy/Caddyfile +++ /dev/null @@ -1,43 +0,0 @@ -# fulmine gateway-h3 edge. -# -# Stock Caddy terminates TLS and h3 on 8443, serves /static/* from disk, -# and forwards the dynamic endpoints to the fulmine server. Both services run -# with network_mode: host, so the server is reachable on loopback. -# -# Only compose.gateway-h3.yml uses this; gateway-64 moved to the nginx edge -# in ../proxy-nginx, which does not speak QUIC in the stock image. -{ - admin off - auto_https off - servers { - protocols h1 h2 h3 - } -} - -https://localhost:8443 { - tls /certs/server.crt /certs/server.key - - # the profile asks the proxy to serve these from disk rather than forward - # them. precompressed prefers the .br / .gz sidecars per Accept-Encoding. - # (root /data + request /static/foo -> /data/static/foo.) - handle /static/* { - root * /data - file_server { - precompressed br gzip - } - } - - # everything else is the fulmine server. Plain h1 with a large keepalive - # pool, so the streams arriving multiplexed over one h2 connection fan out - # across the backend workers instead of queueing behind one upstream. - handle { - reverse_proxy 127.0.0.1:8080 { - transport http { - versions 1.1 - keepalive 5m - keepalive_idle_conns 2048 - keepalive_idle_conns_per_host 2048 - } - } - } -} diff --git a/frameworks/fulmine/proxy/Dockerfile b/frameworks/fulmine/proxy/Dockerfile deleted file mode 100644 index 62d344cf61..0000000000 --- a/frameworks/fulmine/proxy/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -# Stock Caddy, which ships h3 in the base image, so no custom build. It covers -# gateway-h3 (QUIC over UDP) only; gateway-64 uses the nginx edge in -# ../proxy-nginx. -FROM caddy:2-alpine - -COPY Caddyfile /etc/caddy/Caddyfile - -EXPOSE 8443/tcp 8443/udp - -CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] diff --git a/site/data/results/fulmine.js.json b/site/data/results/fulmine.js.json index f9da090602..69363d0553 100644 --- a/site/data/results/fulmine.js.json +++ b/site/data/results/fulmine.js.json @@ -4,44 +4,44 @@ "8gbit-512": { "framework": "fulmine.js", "language": "JS", - "rps": 49296, - "avg_latency": "110.9us", - "p99_latency": "144.0us", - "cpu": "287.7%", - "memory": "2.7GiB", + "rps": 49372, + "avg_latency": "108.2us", + "p99_latency": "147.0us", + "cpu": "309.0%", + "memory": "2.3GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "510.66MB/s", - "input_bw": "481.41MB/s", + "bandwidth": "511.44MB/s", + "input_bw": "482.15MB/s", "reconnects": 0, - "status_2xx": 246550, + "status_2xx": 246928, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "cpu_usec": 15583565, - "cpu_per_req_us": 63.2065, + "cpu_usec": 15642766, + "cpu_per_req_us": 63.3495, "target_rate": 50000, - "rate_ratio": 0.9859, - "p99_9_latency": "6078.0us" + "rate_ratio": 0.9874, + "p99_9_latency": "5282.0us" }, "async-32000": { "framework": "fulmine.js", "language": "JS", - "rps": 2332194, - "avg_latency": "13.64ms", - "p99_latency": "16.10ms", - "cpu": "6366.7%", - "memory": "5.5GiB", + "rps": 2322051, + "avg_latency": "13.69ms", + "p99_latency": "16.00ms", + "cpu": "6368.6%", + "memory": "5.2GiB", "connections": 32000, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "262.40MB/s", - "input_bw": "106.76MB/s", + "bandwidth": "261.26MB/s", + "input_bw": "106.30MB/s", "reconnects": 0, - "status_2xx": 23321941, + "status_2xx": 23220510, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -49,19 +49,19 @@ "async-db-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 219807, - "avg_latency": "4.14ms", - "p99_latency": "18.50ms", - "cpu": "5962.1%", - "memory": "3.6GiB", + "rps": 214728, + "avg_latency": "4.22ms", + "p99_latency": "25.60ms", + "cpu": "5706.8%", + "memory": "3.0GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "842.04MB/s", - "input_bw": "14.67MB/s", - "reconnects": 87420, - "status_2xx": 2198079, + "bandwidth": "822.35MB/s", + "input_bw": "14.33MB/s", + "reconnects": 85424, + "status_2xx": 2147288, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -69,19 +69,114 @@ "baseline-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 1987848, + "rps": 1990740, "avg_latency": "2.06ms", - "p99_latency": "3.20ms", - "cpu": "6750.9%", - "memory": "2.5GiB", + "p99_latency": "3.10ms", + "cpu": "6759.4%", + "memory": "2.1GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "223.97MB/s", + "input_bw": "153.78MB/s", + "reconnects": 0, + "status_2xx": 9953704, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "baseline-h2-1024": { + "framework": "fulmine.js", + "language": "JS", + "rps": 832470, + "avg_latency": "116.50ms", + "p99_latency": "417.33ms", + "cpu": "6406.8%", + "memory": "11.9GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "28.04MB/s", + "reconnects": 0, + "status_2xx": 4212300, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "baseline-h2-256": { + "framework": "fulmine.js", + "language": "JS", + "rps": 955892, + "avg_latency": "28.56ms", + "p99_latency": "193.95ms", + "cpu": "6375.2%", + "memory": "9.8GiB", + "connections": 256, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "32.15MB/s", + "reconnects": 0, + "status_2xx": 4817700, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "baseline-h2c-1024": { + "framework": "fulmine.js", + "language": "JS", + "rps": 972114, + "avg_latency": "103.32ms", + "p99_latency": "894.88ms", + "cpu": "6460.7%", + "memory": "12.3GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "32.75MB/s", + "reconnects": 0, + "status_2xx": 4918900, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "baseline-h2c-256": { + "framework": "fulmine.js", + "language": "JS", + "rps": 1092803, + "avg_latency": "25.43ms", + "p99_latency": "221.32ms", + "cpu": "6282.8%", + "memory": "10.5GiB", + "connections": 256, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "36.68MB/s", + "reconnects": 0, + "status_2xx": 5496800, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "baseline-h2c-4096": { + "framework": "fulmine.js", + "language": "JS", + "rps": 767925, + "avg_latency": "444.16ms", + "p99_latency": "4.98s", + "cpu": "6596.6%", + "memory": "17.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "223.64MB/s", - "input_bw": "153.56MB/s", + "bandwidth": "25.87MB/s", "reconnects": 0, - "status_2xx": 9939242, + "status_2xx": 3924100, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -89,18 +184,18 @@ "echo-ws-16384": { "framework": "fulmine.js", "language": "JS", - "rps": 3582870, - "avg_latency": "4.54ms", - "p99_latency": "8.91ms", - "cpu": "6486.9%", - "memory": "2.2GiB", + "rps": 3567134, + "avg_latency": "4.56ms", + "p99_latency": "8.95ms", + "cpu": "6140.8%", + "memory": "1.9GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "24.43MB/s", + "bandwidth": "24.32MB/s", "reconnects": 0, - "status_2xx": 17914350, + "status_2xx": 17835671, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -108,18 +203,18 @@ "echo-ws-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 3827354, + "rps": 3818148, "avg_latency": "1.07ms", - "p99_latency": "2.28ms", - "cpu": "6524.6%", - "memory": "2.1GiB", + "p99_latency": "2.25ms", + "cpu": "6526.2%", + "memory": "1.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "25.55MB/s", + "bandwidth": "25.49MB/s", "reconnects": 0, - "status_2xx": 19136774, + "status_2xx": 19090740, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -127,18 +222,18 @@ "echo-ws-512": { "framework": "fulmine.js", "language": "JS", - "rps": 3741251, + "rps": 3746798, "avg_latency": "136us", - "p99_latency": "340us", - "cpu": "6513.5%", - "memory": "2.1GiB", + "p99_latency": "360us", + "cpu": "6512.7%", + "memory": "1.8GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "24.97MB/s", + "bandwidth": "25.01MB/s", "reconnects": 0, - "status_2xx": 18706256, + "status_2xx": 18733993, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -146,18 +241,18 @@ "echo-ws-limited-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 2535561, - "avg_latency": "1.07ms", - "p99_latency": "2.68ms", - "cpu": "6226.6%", - "memory": "2.2GiB", + "rps": 2521224, + "avg_latency": "1.08ms", + "p99_latency": "2.58ms", + "cpu": "5933.1%", + "memory": "1.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "57.07MB/s", - "reconnects": 1267862, - "status_2xx": 12677806, + "bandwidth": "56.75MB/s", + "reconnects": 1260604, + "status_2xx": 12606121, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -165,18 +260,18 @@ "echo-ws-limited-512": { "framework": "fulmine.js", "language": "JS", - "rps": 2100669, - "avg_latency": "148us", - "p99_latency": "520us", - "cpu": "5622.4%", - "memory": "2.1GiB", + "rps": 2075909, + "avg_latency": "146us", + "p99_latency": "513us", + "cpu": "5447.7%", + "memory": "1.8GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "47.27MB/s", - "reconnects": 1050367, - "status_2xx": 10503345, + "bandwidth": "46.71MB/s", + "reconnects": 1037990, + "status_2xx": 10379549, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -184,18 +279,18 @@ "echo-ws-pipeline-16384": { "framework": "fulmine.js", "language": "JS", - "rps": 24706873, - "avg_latency": "10.44ms", - "p99_latency": "14.50ms", - "cpu": "6279.4%", - "memory": "2.3GiB", + "rps": 24556236, + "avg_latency": "10.49ms", + "p99_latency": "14.10ms", + "cpu": "6256.6%", + "memory": "2.0GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "165.41MB/s", + "bandwidth": "164.40MB/s", "reconnects": 0, - "status_2xx": 123534368, + "status_2xx": 122781184, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -203,18 +298,18 @@ "echo-ws-pipeline-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 26336032, - "avg_latency": "2.48ms", - "p99_latency": "4.62ms", - "cpu": "6514.4%", - "memory": "2.2GiB", + "rps": 25957948, + "avg_latency": "2.52ms", + "p99_latency": "5.08ms", + "cpu": "6502.5%", + "memory": "1.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "175.85MB/s", + "bandwidth": "173.32MB/s", "reconnects": 0, - "status_2xx": 131680160, + "status_2xx": 129789744, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -222,18 +317,18 @@ "echo-ws-pipeline-512": { "framework": "fulmine.js", "language": "JS", - "rps": 26384259, - "avg_latency": "309us", - "p99_latency": "824us", - "cpu": "6737.9%", - "memory": "2.1GiB", + "rps": 25929427, + "avg_latency": "315us", + "p99_latency": "876us", + "cpu": "6722.8%", + "memory": "1.8GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "176.00MB/s", + "bandwidth": "173.03MB/s", "reconnects": 0, - "status_2xx": 131921296, + "status_2xx": 129647136, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -241,18 +336,18 @@ "fortunes-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 67314, - "avg_latency": "13.94ms", - "p99_latency": "24.20ms", - "cpu": "6509.6%", - "memory": "4.0GiB", + "rps": 68395, + "avg_latency": "13.75ms", + "p99_latency": "22.90ms", + "cpu": "6498.0%", + "memory": "3.6GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.56GB/s", + "bandwidth": "1.58GB/s", "reconnects": 0, - "status_2xx": 336571, + "status_2xx": 341979, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -260,115 +355,115 @@ "gateway-64-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 246369, - "avg_latency": "116.43ms", - "p99_latency": "1.34s", - "cpu": "5005.5%", - "memory": "5.3GiB", + "rps": 224338, + "avg_latency": "126.40ms", + "p99_latency": "1.30s", + "cpu": "4903.2%", + "memory": "5.2GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.05GB/s", + "bandwidth": "2.78GB/s", "reconnects": 0, - "status_2xx": 1246629, + "status_2xx": 1135151, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 373988, - "tpl_baseline": 249325, - "tpl_json": 436320, - "tpl_async_db": 186994, - "cpu_breakdown": "proxy: 2825% 1.7GiB | server: 2180% 3.7GiB" + "tpl_static": 340545, + "tpl_baseline": 227030, + "tpl_json": 397302, + "tpl_async_db": 170272, + "cpu_breakdown": "proxy: 2925% 1.7GiB | server: 1978% 3.5GiB" }, "gateway-64-512": { "framework": "fulmine.js", "language": "JS", - "rps": 257536, - "avg_latency": "59.98ms", - "p99_latency": "528.57ms", - "cpu": "5018.2%", - "memory": "4.7GiB", + "rps": 233639, + "avg_latency": "65.25ms", + "p99_latency": "596.61ms", + "cpu": "4724.0%", + "memory": "4.6GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.15GB/s", + "bandwidth": "2.85GB/s", "reconnects": 0, - "status_2xx": 1300558, + "status_2xx": 1177542, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 390167, - "tpl_baseline": 260111, - "tpl_json": 455195, - "tpl_async_db": 195083, - "cpu_breakdown": "proxy: 2757% 1.4GiB | server: 2261% 3.3GiB" + "tpl_static": 353262, + "tpl_baseline": 235508, + "tpl_json": 412139, + "tpl_async_db": 176631, + "cpu_breakdown": "proxy: 2649% 1.4GiB | server: 2075% 3.2GiB" }, "gateway-h3-256": { "framework": "fulmine.js", "language": "JS", - "rps": 79485, - "avg_latency": "38.91ms", - "p99_latency": "157.59ms", - "cpu": "3367.6%", - "memory": "2.3GiB", + "rps": 192890, + "avg_latency": "42.80ms", + "p99_latency": "163.98ms", + "cpu": "5107.1%", + "memory": "4.6GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "864.72MB/s", + "bandwidth": "2.33GB/s", "reconnects": 0, - "status_2xx": 399814, + "status_2xx": 968312, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 119944, - "tpl_baseline": 79962, - "tpl_json": 139934, - "tpl_async_db": 59972, - "cpu_breakdown": "server: 871% 2.0GiB | proxy: 2497% 389MiB" + "tpl_static": 290493, + "tpl_baseline": 193662, + "tpl_json": 338909, + "tpl_async_db": 145246, + "cpu_breakdown": "server: 1837% 3.2GiB | proxy: 3270% 1.4GiB" }, "gateway-h3-64": { "framework": "fulmine.js", "language": "JS", - "rps": 82633, - "avg_latency": "24.64ms", - "p99_latency": "86.49ms", - "cpu": "3436.2%", - "memory": "3.4GiB", + "rps": 186037, + "avg_latency": "12.84ms", + "p99_latency": "45.66ms", + "cpu": "4542.3%", + "memory": "4.2GiB", "connections": 64, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "896.87MB/s", + "bandwidth": "2.23GB/s", "reconnects": 0, - "status_2xx": 413996, + "status_2xx": 932048, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 124198, - "tpl_baseline": 82799, - "tpl_json": 144898, - "tpl_async_db": 62099, - "cpu_breakdown": "server: 779% 3.1GiB | proxy: 2657% 365MiB" + "tpl_static": 279614, + "tpl_baseline": 186409, + "tpl_json": 326216, + "tpl_async_db": 139807, + "cpu_breakdown": "server: 1679% 3.2GiB | proxy: 2863% 1.0GiB" }, "json-comp-16384": { "framework": "fulmine.js", "language": "JS", - "rps": 424237, - "avg_latency": "38.24ms", - "p99_latency": "88.10ms", - "cpu": "6214.9%", - "memory": "8.2GiB", + "rps": 423792, + "avg_latency": "38.23ms", + "p99_latency": "88.40ms", + "cpu": "6190.6%", + "memory": "7.8GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "565.83MB/s", - "input_bw": "31.56MB/s", - "reconnects": 78301, - "status_2xx": 2121188, + "bandwidth": "565.27MB/s", + "input_bw": "31.52MB/s", + "reconnects": 78579, + "status_2xx": 2118961, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -376,19 +471,57 @@ "json-comp-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 425510, - "avg_latency": "9.62ms", - "p99_latency": "27.30ms", - "cpu": "6265.6%", - "memory": "7.3GiB", + "rps": 426216, + "avg_latency": "9.59ms", + "p99_latency": "26.70ms", + "cpu": "6268.0%", + "memory": "7.0GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "568.56MB/s", + "input_bw": "31.70MB/s", + "reconnects": 83501, + "status_2xx": 2131080, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "json-h2c-1024": { + "framework": "fulmine.js", + "language": "JS", + "rps": 739009, + "avg_latency": "43.93ms", + "p99_latency": "443.44ms", + "cpu": "6400.2%", + "memory": "10.8GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "2.47GB/s", + "reconnects": 0, + "status_2xx": 3732000, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "json-h2c-4096": { + "framework": "fulmine.js", + "language": "JS", + "rps": 591554, + "avg_latency": "216.44ms", + "p99_latency": "3.80s", + "cpu": "6430.3%", + "memory": "13.1GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "567.52MB/s", - "input_bw": "31.65MB/s", - "reconnects": 83516, - "status_2xx": 2127553, + "bandwidth": "1.99GB/s", + "reconnects": 0, + "status_2xx": 3016928, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -396,18 +529,18 @@ "json-tls-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 1143276, - "avg_latency": "3.56ms", - "p99_latency": "90.62ms", - "cpu": "6560.9%", - "memory": "6.5GiB", + "rps": 1213873, + "avg_latency": "3.36ms", + "p99_latency": "97.64ms", + "cpu": "6406.2%", + "memory": "2.1GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.90GB", + "bandwidth": "4.12GB", "reconnects": 0, - "status_2xx": 5831840, + "status_2xx": 6190494, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -416,90 +549,90 @@ "framework": "fulmine.js", "language": "JS", "rps": 9980, - "avg_latency": "80.7us", - "p99_latency": "112.0us", - "cpu": "34.1%", - "memory": "2.0GiB", + "avg_latency": "83.9us", + "p99_latency": "118.0us", + "cpu": "35.3%", + "memory": "1.6GiB", "connections": 1024, "threads": 64, "duration": "20s", "pipeline": 1, "bandwidth": "1.17MB/s", "reconnects": 0, - "status_2xx": 199626, + "status_2xx": 199628, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "cpu_usec": 7148033, - "cpu_per_req_us": 35.8071, + "cpu_usec": 7259496, + "cpu_per_req_us": 36.3651, "target_rate": 10000, "rate_ratio": 0.998, - "p99_9_latency": "160.0us" + "p99_9_latency": "709.0us" }, "latency-1m-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 998321, - "avg_latency": "122.9us", - "p99_latency": "228.0us", - "cpu": "3208.5%", - "memory": "2.4GiB", + "rps": 998195, + "avg_latency": "121.3us", + "p99_latency": "222.0us", + "cpu": "3244.0%", + "memory": "2.0GiB", "connections": 1024, "threads": 64, "duration": "20s", "pipeline": 1, - "bandwidth": "116.80MB/s", + "bandwidth": "116.79MB/s", "reconnects": 0, - "status_2xx": 19969962, + "status_2xx": 19967413, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "cpu_usec": 583625800, - "cpu_per_req_us": 29.2252, + "cpu_usec": 587588963, + "cpu_per_req_us": 29.4274, "target_rate": 1000000, - "rate_ratio": 0.9983, - "p99_9_latency": "5754.0us" + "rate_ratio": 0.9982, + "p99_9_latency": "5434.0us" }, "latency-500k-8cpu-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 391447, - "avg_latency": "2119623.4us", - "p99_latency": "5347328.0us", - "cpu": "788.7%", - "memory": "346MiB", + "rps": 389093, + "avg_latency": "2127574.4us", + "p99_latency": "6031360.0us", + "cpu": "794.9%", + "memory": "293MiB", "connections": 1024, "threads": 64, "duration": "20s", "pipeline": 1, - "bandwidth": "45.80MB/s", + "bandwidth": "45.52MB/s", "reconnects": 0, - "status_2xx": 7831620, + "status_2xx": 7784538, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "cpu_usec": 159570104, - "cpu_per_req_us": 20.3751, + "cpu_usec": 159597861, + "cpu_per_req_us": 20.5019, "target_rate": 500000, - "rate_ratio": 0.7829, - "p99_9_latency": "5769216.0us" + "rate_ratio": 0.7782, + "p99_9_latency": "6506496.0us" }, "limited-conn-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 1767584, - "avg_latency": "2.30ms", - "p99_latency": "9.07ms", - "cpu": "6323.1%", - "memory": "2.5GiB", + "rps": 1771880, + "avg_latency": "2.29ms", + "p99_latency": "9.00ms", + "cpu": "6312.9%", + "memory": "2.1GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "198.86MB/s", - "input_bw": "136.54MB/s", - "reconnects": 883028, - "status_2xx": 8837922, + "bandwidth": "199.35MB/s", + "input_bw": "136.87MB/s", + "reconnects": 886115, + "status_2xx": 8859401, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -507,18 +640,18 @@ "pipelined-4096": { "framework": "fulmine.js", "language": "JS", - "rps": 32392771, - "avg_latency": "2.02ms", - "p99_latency": "4.09ms", - "cpu": "6358.1%", - "memory": "1.9GiB", + "rps": 32558742, + "avg_latency": "2.01ms", + "p99_latency": "3.93ms", + "cpu": "6379.5%", + "memory": "1.5GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "3.56GB/s", + "bandwidth": "3.58GB/s", "reconnects": 0, - "status_2xx": 161963856, + "status_2xx": 162793712, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -526,66 +659,104 @@ "production-stack-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 105424, - "avg_latency": "136.86ms", - "p99_latency": "4.84s", - "cpu": "2989.3%", - "memory": "4.2GiB", + "rps": 109478, + "avg_latency": "102.47ms", + "p99_latency": "2.65s", + "cpu": "2751.5%", + "memory": "3.8GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.18GB/s", + "bandwidth": "1.24GB/s", "reconnects": 0, - "status_2xx": 534503, + "status_2xx": 555057, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 160350, - "tpl_baseline": 53450, - "tpl_items": 267251, - "tpl_me": 53450, - "cpu_breakdown": "edge: 1584% 1.4GiB | authsvc: 747% 503MiB | server: 442% 2.3GiB | cache: 215% 11MiB" + "tpl_static": 166517, + "tpl_baseline": 55505, + "tpl_items": 277528, + "tpl_me": 55505, + "cpu_breakdown": "edge: 1381% 1.4GiB | authsvc: 718% 389MiB | server: 439% 2.0GiB | cache: 213% 12MiB" }, "production-stack-256": { "framework": "fulmine.js", "language": "JS", - "rps": 128139, - "avg_latency": "32.61ms", - "p99_latency": "125.12ms", - "cpu": "2910.5%", - "memory": "3.6GiB", + "rps": 129796, + "avg_latency": "32.24ms", + "p99_latency": "1.12s", + "cpu": "3143.8%", + "memory": "3.3GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.39GB/s", + "bandwidth": "1.41GB/s", "reconnects": 0, - "status_2xx": 644540, + "status_2xx": 652875, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 193362, - "tpl_baseline": 64454, - "tpl_items": 322270, - "tpl_me": 64454, - "cpu_breakdown": "edge: 1379% 1.1GiB | authsvc: 757% 139MiB | server: 567% 2.3GiB | cache: 208% 20MiB" + "tpl_static": 195862, + "tpl_baseline": 65287, + "tpl_items": 326437, + "tpl_me": 65287, + "cpu_breakdown": "edge: 1620% 1.1GiB | authsvc: 738% 133MiB | server: 572% 2.1GiB | cache: 214% 21MiB" + }, + "static-h2-1024": { + "framework": "fulmine.js", + "language": "JS", + "rps": 324467, + "avg_latency": "97.54ms", + "p99_latency": "249.88ms", + "cpu": "6483.6%", + "memory": "11.9GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "4.99GB/s", + "reconnects": 0, + "status_2xx": 1638560, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-h2-256": { + "framework": "fulmine.js", + "language": "JS", + "rps": 352831, + "avg_latency": "24.43ms", + "p99_latency": "141.32ms", + "cpu": "6340.7%", + "memory": "9.4GiB", + "connections": 256, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "5.41GB/s", + "reconnects": 0, + "status_2xx": 1778272, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 }, "static-tls-1024": { "framework": "fulmine.js", "language": "JS", - "rps": 713418, - "avg_latency": "1.42ms", - "p99_latency": "17.64ms", - "cpu": "6527.2%", - "memory": "3.1GiB", + "rps": 708106, + "avg_latency": "1.44ms", + "p99_latency": "15.77ms", + "cpu": "6565.4%", + "memory": "3.3GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "11.00GB", + "bandwidth": "10.92GB", "reconnects": 0, - "status_2xx": 3638554, + "status_2xx": 3611192, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 diff --git a/site/static/logs/baseline-h2/1024/fulmine.log b/site/static/logs/baseline-h2/1024/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/baseline-h2/256/fulmine.log b/site/static/logs/baseline-h2/256/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/baseline-h2c/1024/fulmine.log b/site/static/logs/baseline-h2c/1024/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/baseline-h2c/256/fulmine.log b/site/static/logs/baseline-h2c/256/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/baseline-h2c/4096/fulmine.log b/site/static/logs/baseline-h2c/4096/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/json-h2c/1024/fulmine.log b/site/static/logs/json-h2c/1024/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/json-h2c/4096/fulmine.log b/site/static/logs/json-h2c/4096/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/static-h2/1024/fulmine.log b/site/static/logs/static-h2/1024/fulmine.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/site/static/logs/static-h2/256/fulmine.log b/site/static/logs/static-h2/256/fulmine.log new file mode 100644 index 0000000000..e69de29bb2