diff --git a/frameworks/fulmine/app.js b/frameworks/fulmine/app.js index 0c8405d4e..52c8f6344 100644 --- a/frameworks/fulmine/app.js +++ b/frameworks/fulmine/app.js @@ -151,7 +151,7 @@ if (cluster.isPrimary) { }); // shared by the plaintext listener and the TLS one on 8081: same handler, same shapes - const registerJsonRoute = (target) => target.get('/json/:count', (req, res) => { + const registerJsonRoute = (target, path = '/json/:count') => target.get(path, (req, res) => { if (datasetItems) { let count = parseInt(req.params.count, 10) || 0; if (count < 0) count = 0; @@ -242,7 +242,9 @@ if (cluster.isPrimary) { } }); - app.get('/crud/items/:id', async (req, res) => { + // the cache-aside read, registered under /crud for the crud profile and under /api for + // production-stack, which asks for the same thing behind the edge's JWT check + const itemRead = async (req, res) => { if (!pgPool) return res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"DB not available"}'); const id = parseInt(req.params.id, 10); if (!Number.isFinite(id)) return res.status(404).set(SERVER_HDR).end(); @@ -263,7 +265,8 @@ if (cluster.isPrimary) { } catch (e) { res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"query failed"}'); } - }); + }; + app.get('/crud/items/:id', itemRead); app.post('/crud/items', (req, res) => { if (!pgPool) return res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"DB not available"}'); @@ -310,6 +313,76 @@ if (cluster.isPrimary) { }); }); + // ── production-stack ────────────────────────────────────────────────── + // Four services, and this is the server behind them. The edge terminates TLS, serves + // /static/* itself and sends /api/* past the shared JWT verifier first, so nothing here + // checks a token: what arrives is already authorised and carries X-User-Id. + const USER_TTL_MS = 30000; + const userGet = (id) => { + if (redis) return redis.get('user:' + id); + const hit = crudCache.get('user:' + id); + if (!hit) return null; + if (hit.until <= Date.now()) { crudCache.delete('user:' + id); return null; } + return hit.json; + }; + const userSet = (id, json) => { + if (redis) return redis.set('user:' + id, json, 'PX', USER_TTL_MS); + crudCache.set('user:' + id, { json, until: Date.now() + USER_TTL_MS }); + }; + + app.get('/public/baseline', (req, res) => { + res.set(SERVER_HDR).type('text/plain').send(String(sumQuery(req.query))); + }); + registerJsonRoute(app, '/public/json/:count'); + app.get('/api/items/:id', itemRead); + + // 204 and no body, unlike the crud PUT this otherwise mirrors. The cache entry goes after + // the row is written, so the next read misses and repopulates from Postgres. + app.post('/api/items/:id', (req, res) => { + if (!pgPool) return res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"DB not available"}'); + const id = parseInt(req.params.id, 10); + if (!Number.isFinite(id)) return res.status(404).set(SERVER_HDR).end(); + readJsonBody(req, async (err, body) => { + if (err) return res.status(400).set(SERVER_HDR).end(); + try { + const result = await pgPool.query({ + name: 'crud-update', + text: 'UPDATE items SET name = $1, price = $2, quantity = $3 WHERE id = $4', + values: [body.name ?? 'Updated', body.price ?? 0, body.quantity ?? 0, id] + }); + if (result.rowCount === 0) return res.status(404).set(SERVER_HDR).end(); + await crudDel(id); + res.status(204).set(SERVER_HDR).end(); + } catch (e) { + res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"update failed"}'); + } + }); + }); + + app.get('/api/me', async (req, res) => { + if (!pgPool) return res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"DB not available"}'); + const id = parseInt(req.headers['x-user-id'], 10); + if (!Number.isFinite(id)) return res.status(401).set(SERVER_HDR).end(); + try { + const cached = await userGet(id); + if (cached) { + return res.set(CACHE_HIT_HDR).type('application/json').send(cached); + } + const result = await pgPool.query({ + name: 'user-read', + text: 'SELECT id, name, email, plan FROM users WHERE id = $1 LIMIT 1', + values: [id] + }); + if (result.rows.length === 0) return res.status(404).set(SERVER_HDR).end(); + const u = result.rows[0]; + const json = JSON.stringify({ id: u.id, name: u.name, email: u.email, plan: u.plan }); + userSet(id, json); + res.set(CACHE_MISS_HDR).type('application/json').send(json); + } catch (e) { + res.status(500).set(SERVER_HDR).type('application/json').send('{"error":"query failed"}'); + } + }); + app.post('/upload', (req, res) => { let size = 0; req.on('data', chunk => size += chunk.length); diff --git a/frameworks/fulmine/compose.production-stack.yml b/frameworks/fulmine/compose.production-stack.yml new file mode 100644 index 000000000..7ed42cd05 --- /dev/null +++ b/frameworks/fulmine/compose.production-stack.yml @@ -0,0 +1,86 @@ +# production-stack: edge + cache + authsvc + server, on a 64 logical CPU budget. +# +# edge (caddy) - 32, terminates TLS and h2 and serves /static off disk +# cache (redis) - 2, single threaded on the data path, so more would sit idle +# authsvc (rust) - 8, one HMAC per /api request and nothing else +# server (node) - 22, the rest: JSON, Postgres, Redis client, one worker per core +# +# The edge gets the larger half because it is what saturates: the first run gave the whole stack +# 1537% of CPU against the 1600% its sixteen logical CPUs allow, so the edge was pegged and the +# other three sat idle. Terminating TLS under multiplexed h2 is the expensive half here, and it is +# the knob to sweep first through EDGE_CPUSET and SERVER_CPUSET. +# +# All four on host networking, so what goes between them is loopback rather than a bridge. +# Redis binds 6379, authsvc 9090, server 8080, the edge 8443. +services: + edge: + build: ./proxy-production + network_mode: host + cpuset: "${EDGE_CPUSET:-0-15,64-79}" + ulimits: + memlock: -1 + nofile: + soft: 1048576 + hard: 1048576 + security_opt: + - seccomp:unconfined + volumes: + - ${CERTS_DIR}:/certs:ro + - ${DATA_DIR}/static:/data/static:ro + depends_on: + - authsvc + - server + + cache: + image: redis:7-alpine + network_mode: host + cpuset: "${CACHE_CPUSET:-16,80}" + ulimits: + memlock: -1 + nofile: + soft: 1048576 + hard: 1048576 + security_opt: + - seccomp:unconfined + volumes: + - ${DATA_DIR}/redis-seed.txt:/seed.txt:ro + - ${DATA_DIR}/redis-entrypoint.sh:/entrypoint.sh:ro + entrypoint: ["sh", "/entrypoint.sh"] + + authsvc: + build: ../_shared/authsvc + network_mode: host + cpuset: "${AUTH_CPUSET:-17-20,81-84}" + ulimits: + memlock: -1 + nofile: + soft: 1048576 + hard: 1048576 + security_opt: + - seccomp:unconfined + environment: + - JWT_SECRET=httparena-bench-secret-do-not-use-in-production + - AUTHSVC_LISTEN=0.0.0.0:9090 + + server: + build: + context: . + dockerfile: Dockerfile + network_mode: host + cpuset: "${SERVER_CPUSET:-21-31,85-95}" + ulimits: + memlock: -1 + nofile: + soft: 1048576 + hard: 1048576 + security_opt: + - seccomp:unconfined + environment: + - DATABASE_URL=${DATABASE_URL} + - DATABASE_MAX_CONN=256 + - REDIS_URL=redis://127.0.0.1:6379 + - DATASET_PATH=/data/dataset.json + volumes: + - ${DATA_DIR}/dataset.json:/data/dataset.json:ro + depends_on: + - cache diff --git a/frameworks/fulmine/meta.json b/frameworks/fulmine/meta.json index 49836e47a..742204546 100644 --- a/frameworks/fulmine/meta.json +++ b/frameworks/fulmine/meta.json @@ -25,7 +25,8 @@ "json-tls", "crud", "gateway-64", - "gateway-h3" + "gateway-h3", + "production-stack" ], "maintainers": [ "nigrosimone" diff --git a/frameworks/fulmine/proxy-production/Caddyfile b/frameworks/fulmine/proxy-production/Caddyfile new file mode 100644 index 000000000..a95c2908a --- /dev/null +++ b/frameworks/fulmine/proxy-production/Caddyfile @@ -0,0 +1,52 @@ +# fulmine production-stack edge. +# +# Caddy terminates TLS and h2 on 8443 and splits the three paths the profile defines: +# /static/* off disk here, /public/* straight to the server, /api/* past the shared JWT +# verifier first. The server itself never sees a token, only the X-User-Id that survives. + +{ + admin off + auto_https off + servers { + protocols h1 h2 + } +} + +https://localhost:8443 { + tls /certs/server.crt /certs/server.key + + handle /static/* { + root * /data + file_server { + precompressed br gzip + } + } + + handle /public/* { + reverse_proxy 127.0.0.1:8080 { + transport http { + versions 1.1 + keepalive 5m + keepalive_idle_conns 2048 + keepalive_idle_conns_per_host 2048 + } + } + } + + # authsvc answers 200 with X-User-Id or 401, and forward_auth passes its refusal straight + # back, so an unauthenticated /api/* never reaches the server at all. + handle /api/* { + forward_auth 127.0.0.1:9090 { + uri /_auth + copy_headers X-User-Id + } + 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-production/Dockerfile b/frameworks/fulmine/proxy-production/Dockerfile new file mode 100644 index 000000000..b5e69751c --- /dev/null +++ b/frameworks/fulmine/proxy-production/Dockerfile @@ -0,0 +1,8 @@ +# Stock Caddy again, same as the gateway edge, with the production-stack routing. +FROM caddy:2-alpine + +COPY Caddyfile /etc/caddy/Caddyfile + +EXPOSE 8443/tcp + +CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"] diff --git a/site/data/results/fulmine.json b/site/data/results/fulmine.json index 027640212..7ee5dad43 100644 --- a/site/data/results/fulmine.json +++ b/site/data/results/fulmine.json @@ -4,71 +4,71 @@ "api-16-1024": { "framework": "fulmine", "language": "JS", - "rps": 131175, - "avg_latency": "6.14ms", - "p99_latency": "52.50ms", - "cpu": "1540.6%", - "memory": "1.3GiB", + "rps": 125628, + "avg_latency": "6.42ms", + "p99_latency": "44.70ms", + "cpu": "1495.3%", + "memory": "1.2GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "669.49MB/s", - "input_bw": "7.38MB/s", - "reconnects": 393639, - "status_2xx": 1967626, + "bandwidth": "641.34MB/s", + "input_bw": "7.07MB/s", + "reconnects": 376864, + "status_2xx": 1884424, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 737703, - "tpl_json": 737952, + "tpl_baseline": 706223, + "tpl_json": 706735, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 491970 + "tpl_async_db": 471466 }, "api-4-256": { "framework": "fulmine", "language": "JS", - "rps": 36387, - "avg_latency": "5.91ms", - "p99_latency": "32.10ms", - "cpu": "394.5%", - "memory": "402MiB", + "rps": 35988, + "avg_latency": "5.73ms", + "p99_latency": "29.40ms", + "cpu": "393.8%", + "memory": "426MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "185.64MB/s", - "input_bw": "2.05MB/s", - "reconnects": 109168, - "status_2xx": 545805, + "bandwidth": "183.57MB/s", + "input_bw": "2.02MB/s", + "reconnects": 107976, + "status_2xx": 539826, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 204733, - "tpl_json": 204654, + "tpl_baseline": 202577, + "tpl_json": 202309, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 136418 + "tpl_async_db": 134938 }, "async-db-1024": { "framework": "fulmine", "language": "JS", - "rps": 224608, - "avg_latency": "4.05ms", - "p99_latency": "24.90ms", - "cpu": "5944.0%", - "memory": "3.6GiB", + "rps": 225500, + "avg_latency": "3.98ms", + "p99_latency": "35.40ms", + "cpu": "5633.7%", + "memory": "4.1GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "874.29MB/s", - "input_bw": "14.99MB/s", - "reconnects": 89523, - "status_2xx": 2246080, + "bandwidth": "877.80MB/s", + "input_bw": "15.05MB/s", + "reconnects": 90095, + "status_2xx": 2255000, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -76,19 +76,19 @@ "baseline-4096": { "framework": "fulmine", "language": "JS", - "rps": 1297447, - "avg_latency": "3.16ms", - "p99_latency": "4.42ms", - "cpu": "6797.5%", - "memory": "2.6GiB", + "rps": 1277971, + "avg_latency": "3.21ms", + "p99_latency": "4.38ms", + "cpu": "6785.8%", + "memory": "2.7GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "226.38MB/s", - "input_bw": "100.22MB/s", + "bandwidth": "222.98MB/s", + "input_bw": "98.72MB/s", "reconnects": 0, - "status_2xx": 6487238, + "status_2xx": 6389856, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -96,19 +96,19 @@ "baseline-512": { "framework": "fulmine", "language": "JS", - "rps": 1335278, - "avg_latency": "382us", - "p99_latency": "975us", - "cpu": "6794.8%", + "rps": 1314024, + "avg_latency": "389us", + "p99_latency": "1.01ms", + "cpu": "6826.9%", "memory": "2.6GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "232.98MB/s", - "input_bw": "103.15MB/s", + "bandwidth": "229.27MB/s", + "input_bw": "101.51MB/s", "reconnects": 0, - "status_2xx": 6676391, + "status_2xx": 6570123, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -116,19 +116,19 @@ "crud-4096": { "framework": "fulmine", "language": "JS", - "rps": 355740, - "avg_latency": "11.44ms", - "p99_latency": "20.70ms", - "cpu": "4401.2%", - "memory": "8.1GiB", + "rps": 358280, + "avg_latency": "11.36ms", + "p99_latency": "20.50ms", + "cpu": "4259.9%", + "memory": "8.3GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "140.84MB/s", - "input_bw": "30.53MB/s", - "reconnects": 24570, - "status_2xx": 5336110, + "bandwidth": "142.50MB/s", + "input_bw": "30.75MB/s", + "reconnects": 25083, + "status_2xx": 5374203, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -136,18 +136,18 @@ "echo-ws-16384": { "framework": "fulmine", "language": "JS", - "rps": 3565343, - "avg_latency": "4.56ms", - "p99_latency": "8.94ms", - "cpu": "6209.8%", + "rps": 3550300, + "avg_latency": "4.58ms", + "p99_latency": "9.20ms", + "cpu": "6499.4%", "memory": "2.5GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "24.30MB/s", + "bandwidth": "24.21MB/s", "reconnects": 0, - "status_2xx": 17826718, + "status_2xx": 17751504, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -155,18 +155,18 @@ "echo-ws-4096": { "framework": "fulmine", "language": "JS", - "rps": 3785984, + "rps": 3791854, "avg_latency": "1.08ms", - "p99_latency": "2.31ms", - "cpu": "6549.7%", + "p99_latency": "2.32ms", + "cpu": "6554.3%", "memory": "2.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "25.26MB/s", + "bandwidth": "25.34MB/s", "reconnects": 0, - "status_2xx": 18929921, + "status_2xx": 18959271, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -174,18 +174,18 @@ "echo-ws-512": { "framework": "fulmine", "language": "JS", - "rps": 3705673, - "avg_latency": "137us", - "p99_latency": "362us", - "cpu": "6522.3%", - "memory": "2.3GiB", + "rps": 3728636, + "avg_latency": "136us", + "p99_latency": "377us", + "cpu": "6443.7%", + "memory": "2.4GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "24.73MB/s", + "bandwidth": "24.89MB/s", "reconnects": 0, - "status_2xx": 18528368, + "status_2xx": 18643180, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -193,18 +193,18 @@ "echo-ws-limited-4096": { "framework": "fulmine", "language": "JS", - "rps": 2557031, - "avg_latency": "1.07ms", - "p99_latency": "2.87ms", - "cpu": "6232.9%", + "rps": 2558787, + "avg_latency": "1.06ms", + "p99_latency": "3.28ms", + "cpu": "5956.0%", "memory": "2.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "57.56MB/s", - "reconnects": 1278194, - "status_2xx": 12785156, + "bandwidth": "57.64MB/s", + "reconnects": 1278357, + "status_2xx": 12793936, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -212,18 +212,18 @@ "echo-ws-limited-512": { "framework": "fulmine", "language": "JS", - "rps": 2083680, - "avg_latency": "146us", - "p99_latency": "532us", - "cpu": "5585.6%", + "rps": 2084867, + "avg_latency": "147us", + "p99_latency": "533us", + "cpu": "5601.9%", "memory": "2.4GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "46.89MB/s", - "reconnects": 1041876, - "status_2xx": 10418400, + "bandwidth": "46.91MB/s", + "reconnects": 1042470, + "status_2xx": 10424337, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -231,18 +231,18 @@ "echo-ws-pipeline-16384": { "framework": "fulmine", "language": "JS", - "rps": 23533654, - "avg_latency": "10.91ms", - "p99_latency": "15.50ms", - "cpu": "6309.9%", + "rps": 23721667, + "avg_latency": "10.87ms", + "p99_latency": "14.90ms", + "cpu": "6353.5%", "memory": "2.6GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "157.57MB/s", + "bandwidth": "158.84MB/s", "reconnects": 0, - "status_2xx": 117668272, + "status_2xx": 118608336, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -250,18 +250,18 @@ "echo-ws-pipeline-4096": { "framework": "fulmine", "language": "JS", - "rps": 24778835, - "avg_latency": "2.64ms", - "p99_latency": "5.44ms", - "cpu": "6573.8%", + "rps": 24879625, + "avg_latency": "2.63ms", + "p99_latency": "5.37ms", + "cpu": "6586.0%", "memory": "2.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "165.46MB/s", + "bandwidth": "166.13MB/s", "reconnects": 0, - "status_2xx": 123894176, + "status_2xx": 124398128, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -269,18 +269,18 @@ "echo-ws-pipeline-512": { "framework": "fulmine", "language": "JS", - "rps": 24580339, - "avg_latency": "332us", - "p99_latency": "961us", - "cpu": "6740.0%", - "memory": "2.3GiB", + "rps": 24928620, + "avg_latency": "327us", + "p99_latency": "905us", + "cpu": "6783.7%", + "memory": "2.4GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "164.05MB/s", + "bandwidth": "166.35MB/s", "reconnects": 0, - "status_2xx": 122901696, + "status_2xx": 124643104, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -288,115 +288,115 @@ "gateway-64-1024": { "framework": "fulmine", "language": "JS", - "rps": 82340, - "avg_latency": "336.49ms", - "p99_latency": "4.78s", - "cpu": "4268.4%", - "memory": "6.7GiB", + "rps": 81019, + "avg_latency": "342.96ms", + "p99_latency": "4.49s", + "cpu": "4139.8%", + "memory": "6.0GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "969.29MB/s", + "bandwidth": "957.04MB/s", "reconnects": 0, - "status_2xx": 415819, + "status_2xx": 409960, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 124745, - "tpl_baseline": 83163, - "tpl_json": 145536, - "tpl_async_db": 62372, - "cpu_breakdown": "proxy: 3148% 4.3GiB | server: 1120% 2.3GiB" + "tpl_static": 122988, + "tpl_baseline": 81992, + "tpl_json": 143486, + "tpl_async_db": 61494, + "cpu_breakdown": "proxy: 3119% 4.1GiB | server: 1021% 1.9GiB" }, "gateway-64-512": { "framework": "fulmine", "language": "JS", - "rps": 88935, - "avg_latency": "171.71ms", - "p99_latency": "1.97s", - "cpu": "4318.6%", - "memory": "4.5GiB", + "rps": 89194, + "avg_latency": "170.52ms", + "p99_latency": "2.32s", + "cpu": "4301.6%", + "memory": "4.6GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "999.86MB/s", + "bandwidth": "1004.78MB/s", "reconnects": 0, - "status_2xx": 448233, + "status_2xx": 449542, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 134469, - "tpl_baseline": 89646, - "tpl_json": 156881, - "tpl_async_db": 67234, - "cpu_breakdown": "proxy: 3206% 2.1GiB | server: 1113% 2.4GiB" + "tpl_static": 134862, + "tpl_baseline": 89908, + "tpl_json": 157339, + "tpl_async_db": 67431, + "cpu_breakdown": "proxy: 3137% 2.3GiB | server: 1165% 2.4GiB" }, "gateway-h3-256": { "framework": "fulmine", "language": "JS", - "rps": 62791, - "avg_latency": "126.37ms", - "p99_latency": "745.76ms", - "cpu": "2626.4%", - "memory": "3.7GiB", + "rps": 63011, + "avg_latency": "126.57ms", + "p99_latency": "745.63ms", + "cpu": "2649.1%", + "memory": "3.2GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "665.78MB/s", + "bandwidth": "668.61MB/s", "reconnects": 0, - "status_2xx": 315843, + "status_2xx": 316949, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 94752, - "tpl_baseline": 63168, - "tpl_json": 110545, - "tpl_async_db": 47376, - "cpu_breakdown": "server: 712% 1.9GiB | proxy: 1915% 1.8GiB" + "tpl_static": 95084, + "tpl_baseline": 63389, + "tpl_json": 110932, + "tpl_async_db": 47542, + "cpu_breakdown": "server: 730% 1.8GiB | proxy: 1919% 1.4GiB" }, "gateway-h3-64": { "framework": "fulmine", "language": "JS", - "rps": 91075, - "avg_latency": "22.37ms", - "p99_latency": "82.88ms", - "cpu": "3590.5%", + "rps": 91841, + "avg_latency": "22.17ms", + "p99_latency": "81.23ms", + "cpu": "3599.2%", "memory": "2.6GiB", "connections": 64, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "987.63MB/s", + "bandwidth": "996.70MB/s", "reconnects": 0, - "status_2xx": 456286, + "status_2xx": 460128, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_static": 136885, - "tpl_baseline": 91257, - "tpl_json": 159700, - "tpl_async_db": 68442, - "cpu_breakdown": "server: 1016% 2.2GiB | proxy: 2574% 421MiB" + "tpl_static": 138038, + "tpl_baseline": 92025, + "tpl_json": 161044, + "tpl_async_db": 69019, + "cpu_breakdown": "server: 1012% 2.2GiB | proxy: 2587% 426MiB" }, "json-4096": { "framework": "fulmine", "language": "JS", - "rps": 1141084, - "avg_latency": "3.22ms", - "p99_latency": "9.98ms", - "cpu": "6444.0%", + "rps": 1135231, + "avg_latency": "3.23ms", + "p99_latency": "9.85ms", + "cpu": "6462.4%", "memory": "2.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.94GB/s", - "input_bw": "54.41MB/s", - "reconnects": 226492, - "status_2xx": 5705420, + "bandwidth": "3.92GB/s", + "input_bw": "54.13MB/s", + "reconnects": 225271, + "status_2xx": 5676157, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -404,19 +404,19 @@ "json-comp-16384": { "framework": "fulmine", "language": "JS", - "rps": 374554, - "avg_latency": "43.32ms", - "p99_latency": "100.40ms", - "cpu": "6309.4%", - "memory": "10.3GiB", + "rps": 372409, + "avg_latency": "43.53ms", + "p99_latency": "100.80ms", + "cpu": "6319.7%", + "memory": "10.4GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "514.56MB/s", - "input_bw": "27.86MB/s", - "reconnects": 66369, - "status_2xx": 1872771, + "bandwidth": "511.62MB/s", + "input_bw": "27.70MB/s", + "reconnects": 66022, + "status_2xx": 1862048, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -424,19 +424,19 @@ "json-comp-4096": { "framework": "fulmine", "language": "JS", - "rps": 356319, - "avg_latency": "11.46ms", - "p99_latency": "37.10ms", - "cpu": "6407.9%", + "rps": 356281, + "avg_latency": "11.48ms", + "p99_latency": "36.60ms", + "cpu": "6376.5%", "memory": "9.0GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "489.46MB/s", - "input_bw": "26.51MB/s", - "reconnects": 69496, - "status_2xx": 1781596, + "bandwidth": "489.40MB/s", + "input_bw": "26.50MB/s", + "reconnects": 69595, + "status_2xx": 1781407, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -444,19 +444,19 @@ "json-comp-512": { "framework": "fulmine", "language": "JS", - "rps": 341669, + "rps": 341959, "avg_latency": "1.49ms", - "p99_latency": "10.70ms", - "cpu": "6164.5%", - "memory": "8.0GiB", + "p99_latency": "7.58ms", + "cpu": "6239.2%", + "memory": "8.1GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "469.38MB/s", - "input_bw": "25.42MB/s", - "reconnects": 68343, - "status_2xx": 1708346, + "bandwidth": "469.81MB/s", + "input_bw": "25.44MB/s", + "reconnects": 68402, + "status_2xx": 1709795, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -464,18 +464,18 @@ "json-tls-4096": { "framework": "fulmine", "language": "JS", - "rps": 1076676, - "avg_latency": "3.78ms", - "p99_latency": "54.63ms", - "cpu": "6585.5%", + "rps": 1069770, + "avg_latency": "3.80ms", + "p99_latency": "52.49ms", + "cpu": "6587.9%", "memory": "2.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.72GB", + "bandwidth": "3.70GB", "reconnects": 0, - "status_2xx": 5490408, + "status_2xx": 5455284, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -483,19 +483,19 @@ "limited-conn-4096": { "framework": "fulmine", "language": "JS", - "rps": 1175660, - "avg_latency": "3.47ms", - "p99_latency": "14.40ms", - "cpu": "6459.1%", + "rps": 1157560, + "avg_latency": "3.52ms", + "p99_latency": "14.80ms", + "cpu": "6458.8%", "memory": "2.7GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "205.12MB/s", - "input_bw": "90.82MB/s", - "reconnects": 587871, - "status_2xx": 5878301, + "bandwidth": "201.96MB/s", + "input_bw": "89.42MB/s", + "reconnects": 578244, + "status_2xx": 5787800, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -503,19 +503,19 @@ "limited-conn-512": { "framework": "fulmine", "language": "JS", - "rps": 1096830, - "avg_latency": "456us", - "p99_latency": "2.03ms", - "cpu": "6156.2%", + "rps": 1079317, + "avg_latency": "464us", + "p99_latency": "2.11ms", + "cpu": "6208.4%", "memory": "2.6GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "191.37MB/s", - "input_bw": "84.73MB/s", - "reconnects": 548409, - "status_2xx": 5484153, + "bandwidth": "188.32MB/s", + "input_bw": "83.37MB/s", + "reconnects": 539663, + "status_2xx": 5396589, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -523,10 +523,10 @@ "pipelined-4096": { "framework": "fulmine", "language": "JS", - "rps": 7868038, - "avg_latency": "8.33ms", + "rps": 7877142, + "avg_latency": "8.31ms", "p99_latency": "10.80ms", - "cpu": "6575.8%", + "cpu": "6570.8%", "memory": "2.6GiB", "connections": 4096, "threads": 64, @@ -534,7 +534,7 @@ "pipeline": 16, "bandwidth": "1.34GB/s", "reconnects": 0, - "status_2xx": 39340191, + "status_2xx": 39385712, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -542,10 +542,10 @@ "pipelined-512": { "framework": "fulmine", "language": "JS", - "rps": 7917830, - "avg_latency": "1.03ms", - "p99_latency": "2.52ms", - "cpu": "6580.3%", + "rps": 7896918, + "avg_latency": "1.04ms", + "p99_latency": "2.65ms", + "cpu": "6572.1%", "memory": "2.5GiB", "connections": 512, "threads": 64, @@ -553,26 +553,74 @@ "pipeline": 16, "bandwidth": "1.35GB/s", "reconnects": 0, - "status_2xx": 39589152, + "status_2xx": 39484592, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 }, + "production-stack-1024": { + "framework": "fulmine", + "language": "JS", + "rps": 50374, + "avg_latency": "317.25ms", + "p99_latency": "1.80s", + "cpu": "3916.2%", + "memory": "5.5GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "516.07MB/s", + "reconnects": 0, + "status_2xx": 254896, + "status_3xx": 0, + "status_4xx": 147, + "status_5xx": 0, + "tpl_static": 76468, + "tpl_baseline": 25489, + "tpl_items": 127448, + "tpl_me": 25489, + "cpu_breakdown": "edge: 2820% 3.1GiB | authsvc: 466% 216MiB | server: 630% 2.4GiB" + }, + "production-stack-256": { + "framework": "fulmine", + "language": "JS", + "rps": 59123, + "avg_latency": "71.28ms", + "p99_latency": "946.34ms", + "cpu": "4058.8%", + "memory": "3.4GiB", + "connections": 256, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "569.51MB/s", + "reconnects": 0, + "status_2xx": 297980, + "status_3xx": 0, + "status_4xx": 367, + "status_5xx": 0, + "tpl_static": 89394, + "tpl_baseline": 29798, + "tpl_items": 148990, + "tpl_me": 29798, + "cpu_breakdown": "edge: 2991% 878MiB | authsvc: 498% 60MiB | server: 569% 2.4GiB" + }, "static-1024": { "framework": "fulmine", "language": "JS", - "rps": 540509, - "avg_latency": "1.98ms", - "p99_latency": "25.80ms", - "cpu": "6505.3%", - "memory": "3.9GiB", + "rps": 532953, + "avg_latency": "2.07ms", + "p99_latency": "29.30ms", + "cpu": "6502.3%", + "memory": "4.2GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "8.29GB", + "bandwidth": "8.17GB", "reconnects": 0, - "status_2xx": 2756630, + "status_2xx": 2718036, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -580,18 +628,18 @@ "static-4096": { "framework": "fulmine", "language": "JS", - "rps": 582701, - "avg_latency": "7.18ms", - "p99_latency": "45.49ms", - "cpu": "6498.8%", - "memory": "7.5GiB", + "rps": 578692, + "avg_latency": "7.25ms", + "p99_latency": "51.50ms", + "cpu": "6520.8%", + "memory": "7.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "8.94GB", + "bandwidth": "8.88GB", "reconnects": 0, - "status_2xx": 2972251, + "status_2xx": 2951349, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -599,18 +647,18 @@ "static-6800": { "framework": "fulmine", "language": "JS", - "rps": 567379, - "avg_latency": "12.07ms", - "p99_latency": "58.06ms", - "cpu": "6558.9%", + "rps": 558769, + "avg_latency": "12.28ms", + "p99_latency": "58.08ms", + "cpu": "6476.2%", "memory": "7.6GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "8.70GB", + "bandwidth": "8.57GB", "reconnects": 0, - "status_2xx": 2893919, + "status_2xx": 2850137, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -618,18 +666,18 @@ "static-tls-1024": { "framework": "fulmine", "language": "JS", - "rps": 432837, - "avg_latency": "2.42ms", - "p99_latency": "27.46ms", - "cpu": "6513.3%", - "memory": "3.7GiB", + "rps": 430985, + "avg_latency": "2.45ms", + "p99_latency": "26.34ms", + "cpu": "6510.8%", + "memory": "4.5GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "6.64GB", + "bandwidth": "6.61GB", "reconnects": 0, - "status_2xx": 2207417, + "status_2xx": 2198016, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -637,18 +685,18 @@ "static-tls-4096": { "framework": "fulmine", "language": "JS", - "rps": 463875, - "avg_latency": "8.93ms", - "p99_latency": "74.99ms", - "cpu": "6457.0%", - "memory": "7.2GiB", + "rps": 456896, + "avg_latency": "9.09ms", + "p99_latency": "75.34ms", + "cpu": "6451.5%", + "memory": "7.5GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "7.11GB", + "bandwidth": "7.01GB", "reconnects": 0, - "status_2xx": 2365822, + "status_2xx": 2330590, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -656,18 +704,18 @@ "static-tls-6800": { "framework": "fulmine", "language": "JS", - "rps": 452587, - "avg_latency": "15.11ms", - "p99_latency": "147.50ms", - "cpu": "6380.7%", + "rps": 447603, + "avg_latency": "15.31ms", + "p99_latency": "163.12ms", + "cpu": "6344.8%", "memory": "7.6GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "6.94GB", + "bandwidth": "6.86GB", "reconnects": 0, - "status_2xx": 2305970, + "status_2xx": 2282017, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -675,19 +723,19 @@ "upload-256": { "framework": "fulmine", "language": "JS", - "rps": 2161, - "avg_latency": "113.50ms", - "p99_latency": "949.90ms", - "cpu": "6256.9%", - "memory": "7.5GiB", + "rps": 2125, + "avg_latency": "115.79ms", + "p99_latency": "929.90ms", + "cpu": "6345.8%", + "memory": "7.4GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "397.59KB/s", - "input_bw": "17.14GB/s", - "reconnects": 2159, - "status_2xx": 10830, + "bandwidth": "391.21KB/s", + "input_bw": "16.86GB/s", + "reconnects": 2108, + "status_2xx": 10651, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -695,19 +743,19 @@ "upload-32": { "framework": "fulmine", "language": "JS", - "rps": 2037, - "avg_latency": "15.69ms", - "p99_latency": "96.90ms", - "cpu": "3081.7%", - "memory": "6.6GiB", + "rps": 2031, + "avg_latency": "15.71ms", + "p99_latency": "99.80ms", + "cpu": "3141.1%", + "memory": "6.8GiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "374.28KB/s", - "input_bw": "16.16GB/s", - "reconnects": 2041, - "status_2xx": 10187, + "bandwidth": "373.36KB/s", + "input_bw": "16.11GB/s", + "reconnects": 2031, + "status_2xx": 10159, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 diff --git a/site/static/logs/production-stack/1024/fulmine.log b/site/static/logs/production-stack/1024/fulmine.log new file mode 100644 index 000000000..ae9de49b5 --- /dev/null +++ b/site/static/logs/production-stack/1024/fulmine.log @@ -0,0 +1 @@ +Error response from daemon: No such container: httparena-bench-fulmine diff --git a/site/static/logs/production-stack/256/fulmine.log b/site/static/logs/production-stack/256/fulmine.log new file mode 100644 index 000000000..ae9de49b5 --- /dev/null +++ b/site/static/logs/production-stack/256/fulmine.log @@ -0,0 +1 @@ +Error response from daemon: No such container: httparena-bench-fulmine