From b164ee93652e183c1b923d904ed32e66deb92d39 Mon Sep 17 00:00:00 2001 From: MDA2AV Date: Fri, 21 Aug 2026 23:55:42 +0100 Subject: [PATCH 1/2] vertx: the seven profiles it was missing static, static-tls, json-tls, async-db, crud, api-4 and api-16. The entry carried four endpoints; api-4 and api-16 rotate over /baseline11, /json and /async-db, so wiring Postgres brings all three profiles with it. json-tls and static-tls listen on 8081. The verticle is already deployed once per core, so having each instance bind both ports spreads the TLS listener across every event loop rather than parking it on one - the failure #1245 fixed on quarkus. ALPN is off: those two profiles want HTTP/1.1 and no h2 offered. Postgres goes through the reactive pg client, one pool per verticle instance so the harness's connection budget is split across them. postgres:18 negotiates SCRAM-SHA-256, which the client leaves to com.ongres.scram. tags is a JSONB column, so the client hands back a JsonArray rather than text - reading it as a String threw and left async-db and crud answering with an empty body and no content type. Static file bodies are read from disk on every request; sendFile hands the descriptor to the kernel and the pre-compressed sibling is picked per request. crud runs cache-aside on Redis through the vertx redis client, with a 200ms TTL and an explicit delete on update. Validation: 58 passed, 0 failed. --- frameworks/vertx/README.md | 15 + frameworks/vertx/meta.json | 9 +- frameworks/vertx/pom.xml | 16 + .../main/java/httparena/ServerVerticle.java | 325 +++++++++++++++++- 4 files changed, 363 insertions(+), 2 deletions(-) diff --git a/frameworks/vertx/README.md b/frameworks/vertx/README.md index 3c31f2536..c5a11dc89 100644 --- a/frameworks/vertx/README.md +++ b/frameworks/vertx/README.md @@ -17,6 +17,11 @@ Eclipse Vert.x with vertx-web on Netty, one server verticle per core. | `/baseline11` | POST | Sums query parameters + request body | | `/json/{count}?m=N` | GET | First `count` dataset items with `total = price * quantity * m` | | `/upload` | POST | Streams the body and returns the byte count | +| `/baseline2` | GET | Sums query parameter values | +| `/async-db` | GET | Reads from PostgreSQL through the reactive pg client | +| `/static/:filename` | GET | Serves a file from disk with `sendFile`, the brotli or gzip variant when the client accepts one | +| `/crud/items` | GET/POST | Lists items by category with paging, or inserts one | +| `/crud/items/:id` | GET/PUT | Reads one item through a Redis cache-aside, or updates it and drops the cached copy | ## Notes @@ -25,3 +30,13 @@ Eclipse Vert.x with vertx-web on Netty, one server verticle per core. - Compression through `HttpServerOptions.setCompressionSupported(true)` - The verticle is deployed once per core, all instances sharing port 8080 - `/upload` is read from the request stream, so the 20 MB body is never buffered + +`json-tls` and `static-tls` listen on `8081` when `/certs/server.crt` and `/certs/server.key` are +mounted. The verticle is deployed once per core and each instance binds both ports, so the TLS +listener is spread across every event loop rather than parked on one. ALPN is off: those two +profiles want HTTP/1.1 negotiated and no h2 offered. + +Static file bodies are read from disk on every request - `sendFile` hands the descriptor to the +kernel rather than holding the bytes - and the pre-compressed sibling is picked per request. + +`tags` is a JSONB column, so the pg client hands back a `JsonArray` rather than text. diff --git a/frameworks/vertx/meta.json b/frameworks/vertx/meta.json index 61316b984..47c516fa1 100644 --- a/frameworks/vertx/meta.json +++ b/frameworks/vertx/meta.json @@ -19,7 +19,14 @@ "limited-conn", "json", "json-comp", - "upload" + "json-tls", + "upload", + "static", + "static-tls", + "async-db", + "crud", + "api-4", + "api-16" ], "maintainers": [] } diff --git a/frameworks/vertx/pom.xml b/frameworks/vertx/pom.xml index 045952db7..85b842d17 100644 --- a/frameworks/vertx/pom.xml +++ b/frameworks/vertx/pom.xml @@ -26,6 +26,22 @@ vertx-web ${vertx.version} + + io.vertx + vertx-pg-client + ${vertx.version} + + + + com.ongres.scram + scram-client + 3.1 + + + io.vertx + vertx-redis-client + ${vertx.version} + diff --git a/frameworks/vertx/src/main/java/httparena/ServerVerticle.java b/frameworks/vertx/src/main/java/httparena/ServerVerticle.java index d1f2988de..9ec195586 100644 --- a/frameworks/vertx/src/main/java/httparena/ServerVerticle.java +++ b/frameworks/vertx/src/main/java/httparena/ServerVerticle.java @@ -1,5 +1,7 @@ package httparena; +import java.io.File; +import java.util.List; import java.util.Map; import io.vertx.core.Future; @@ -8,30 +10,77 @@ import io.vertx.core.http.HttpServerRequest; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; +import io.vertx.core.net.PemKeyCertOptions; import io.vertx.ext.web.Router; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.handler.BodyHandler; +import io.vertx.pgclient.PgBuilder; +import io.vertx.pgclient.PgConnectOptions; +import io.vertx.redis.client.Redis; +import io.vertx.redis.client.RedisAPI; +import io.vertx.sqlclient.Pool; +import io.vertx.sqlclient.PoolOptions; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.Tuple; public class ServerVerticle extends VerticleBase { private static final long MAX_BODY = 25L * 1024 * 1024; + private static final String STATIC_ROOT = "/data/static"; + private static final String CERT = "/certs/server.crt"; + private static final String KEY = "/certs/server.key"; + + private static final String ITEM_COLUMNS = + "id, name, category, price, quantity, active, tags, rating_score, rating_count"; + + // The profile reads and writes the same ids, so a long TTL would answer from a copy + // the writes have already moved past. + private static final String CRUD_TTL_MS = "200"; private final JsonArray dataset; + private Pool pgPool; + private RedisAPI redis; + public ServerVerticle(JsonArray dataset) { this.dataset = dataset; } @Override public Future start() { + String dbUrl = System.getenv("DATABASE_URL"); + if (dbUrl != null && !dbUrl.isEmpty()) { + // The pool is per verticle instance and one is deployed per core, so the + // harness's connection budget is split across them rather than opened by each. + pgPool = PgBuilder.pool() + .connectingTo(PgConnectOptions.fromUri(dbUrl)) + .with(new PoolOptions().setMaxSize(4)) + .using(vertx) + .build(); + } + String redisUrl = System.getenv("REDIS_URL"); + if (redisUrl != null && !redisUrl.isEmpty()) { + redis = RedisAPI.api(Redis.createClient(vertx, redisUrl)); + } Router router = Router.router(vertx); router.get("/pipeline").handler(ctx -> text(ctx, "ok")); + router.get("/baseline2").handler(this::baselineGet); router.get("/baseline11").handler(this::baselineGet); router.post("/baseline11") .handler(BodyHandler.create().setBodyLimit(MAX_BODY)) .handler(this::baselinePost); router.get("/json/:count").handler(this::jsonItems); + router.get("/async-db").handler(this::asyncDb); + router.get("/static/:filename").handler(this::staticFile); + router.get("/crud/items").handler(this::crudList); + router.post("/crud/items") + .handler(BodyHandler.create()) + .handler(this::crudCreate); + router.get("/crud/items/:id").handler(this::crudRead); + router.put("/crud/items/:id") + .handler(BodyHandler.create()) + .handler(this::crudUpdate); router.post("/upload").handler(this::upload); HttpServerOptions options = new HttpServerOptions() @@ -39,13 +88,40 @@ public Future start() { .setPort(8080) .setCompressionSupported(true); - return vertx.createHttpServer(options).requestHandler(router).listen(); + Future plain = vertx.createHttpServer(options).requestHandler(router).listen(); + + // json-tls and static-tls on 8081, the same router behind TLS. This verticle is + // deployed once per core, so every instance binds both ports and the listener is + // spread across all the event loops rather than parked on one. ALPN is off: the + // two profiles want HTTP/1.1 negotiated and no h2 offered. The harness only mounts + // /certs for the TLS profiles. + if (new File(CERT).isFile() && new File(KEY).isFile()) { + HttpServerOptions tls = new HttpServerOptions() + .setHost("0.0.0.0") + .setPort(8081) + .setCompressionSupported(true) + .setSsl(true) + .setUseAlpn(false) + .setKeyCertOptions(new PemKeyCertOptions().setCertPath(CERT).setKeyPath(KEY)); + return Future.all(plain, vertx.createHttpServer(tls).requestHandler(router).listen()); + } + return plain; } private void text(RoutingContext ctx, String body) { ctx.response().putHeader("content-type", "text/plain").end(body); } + private void json(RoutingContext ctx, String body) { + ctx.response().putHeader("content-type", "application/json").end(body); + } + + private void dbError(RoutingContext ctx, String message, int status) { + ctx.response().setStatusCode(status) + .putHeader("content-type", "application/json") + .end("{\"error\":\"" + message + "\"}"); + } + private long querySum(RoutingContext ctx) { long sum = 0; for (Map.Entry entry : ctx.queryParams()) { @@ -57,6 +133,16 @@ private long querySum(RoutingContext ctx) { return sum; } + private int intParam(RoutingContext ctx, String name, int fallback) { + String raw = ctx.queryParams().get(name); + if (raw == null) return fallback; + try { + return Integer.parseInt(raw.trim()); + } catch (NumberFormatException e) { + return fallback; + } + } + private void baselineGet(RoutingContext ctx) { text(ctx, Long.toString(querySum(ctx))); } @@ -100,6 +186,243 @@ private void jsonItems(RoutingContext ctx) { ctx.json(new JsonObject().put("items", items).put("count", count)); } + // tags is a JSONB column, so the client hands back a JsonArray rather than text. + private JsonArray tags(Row row) { + Object value = row.getValue("tags"); + if (value instanceof JsonArray array) return array; + if (value instanceof String text) return new JsonArray(text); + return new JsonArray(); + } + + private JsonObject itemShape(Row row) { + return new JsonObject() + .put("id", row.getLong("id")) + .put("name", row.getString("name")) + .put("category", row.getString("category")) + .put("price", row.getLong("price")) + .put("quantity", row.getLong("quantity")) + .put("active", row.getBoolean("active")) + .put("tags", tags(row)) + .put("rating", new JsonObject() + .put("score", row.getLong("rating_score")) + .put("count", row.getLong("rating_count"))); + } + + private void asyncDb(RoutingContext ctx) { + if (pgPool == null) { + json(ctx, "{\"items\":[],\"count\":0}"); + return; + } + int min = intParam(ctx, "min", 10); + int max = intParam(ctx, "max", 50); + int limit = Math.max(1, Math.min(50, intParam(ctx, "limit", 50))); + + pgPool.preparedQuery("SELECT " + ITEM_COLUMNS + " FROM items WHERE price BETWEEN $1 AND $2 LIMIT $3") + .execute(Tuple.of(min, max, limit)) + .onSuccess(rows -> { + JsonArray items = new JsonArray(); + for (Row row : rows) items.add(itemShape(row)); + json(ctx, new JsonObject().put("items", items).put("count", items.size()).encode()); + }) + .onFailure(e -> json(ctx, "{\"items\":[],\"count\":0}")); + } + + // Standard mode still reads static bodies from disk on every request: sendFile hands + // the descriptor to the kernel rather than holding the bytes. The pre-compressed + // sibling is picked per request and is also read from disk. + private void staticFile(RoutingContext ctx) { + String filename = ctx.pathParam("filename"); + if (filename == null || filename.contains("/") || filename.contains("..")) { + ctx.response().setStatusCode(404).end(); + return; + } + String path = STATIC_ROOT + "/" + filename; + if (!new File(path).isFile()) { + ctx.response().setStatusCode(404).end(); + return; + } + ctx.response().putHeader("content-type", contentType(filename)); + + String accept = ctx.request().getHeader("accept-encoding"); + if (accept != null) { + if (accept.contains("br") && new File(path + ".br").isFile()) { + ctx.response().putHeader("content-encoding", "br").sendFile(path + ".br"); + return; + } + if (accept.contains("gzip") && new File(path + ".gz").isFile()) { + ctx.response().putHeader("content-encoding", "gzip").sendFile(path + ".gz"); + return; + } + } + ctx.response().sendFile(path); + } + + private String contentType(String filename) { + int dot = filename.lastIndexOf('.'); + String ext = dot < 0 ? "" : filename.substring(dot); + return switch (ext) { + case ".css" -> "text/css"; + case ".js" -> "application/javascript"; + case ".html" -> "text/html"; + case ".woff2" -> "font/woff2"; + case ".svg" -> "image/svg+xml"; + case ".webp" -> "image/webp"; + case ".json" -> "application/json"; + default -> "application/octet-stream"; + }; + } + + private void crudList(RoutingContext ctx) { + if (pgPool == null) { + dbError(ctx, "DB not available", 500); + return; + } + String category = ctx.queryParams().get("category"); + if (category == null) category = "electronics"; + int page = Math.max(1, intParam(ctx, "page", 1)); + int limit = Math.max(1, Math.min(50, intParam(ctx, "limit", 10))); + + pgPool.preparedQuery("SELECT " + ITEM_COLUMNS + " FROM items WHERE category = $1 ORDER BY id LIMIT $2 OFFSET $3") + .execute(Tuple.of(category, limit, (page - 1) * limit)) + .onSuccess(rows -> { + JsonArray items = new JsonArray(); + for (Row row : rows) items.add(itemShape(row)); + json(ctx, new JsonObject() + .put("items", items) + .put("total", items.size()) + .put("page", page) + .put("limit", limit) + .encode()); + }) + .onFailure(e -> dbError(ctx, "query failed", 500)); + } + + private void crudCreate(RoutingContext ctx) { + if (pgPool == null) { + dbError(ctx, "DB not available", 500); + return; + } + JsonObject body = ctx.body().asJsonObject(); + if (body == null) { + dbError(ctx, "insert failed", 500); + return; + } + pgPool.preparedQuery("INSERT INTO items (id, name, category, price, quantity, active, tags, rating_score, rating_count) " + + "VALUES ($1, $2, $3, $4, $5, true, '[\"bench\"]', 0, 0) " + + "ON CONFLICT (id) DO UPDATE SET name = $2, price = $4, quantity = $5 RETURNING id") + .execute(Tuple.of( + body.getLong("id"), + body.getString("name", "New Product"), + body.getString("category", "test"), + body.getLong("price", 0L), + body.getLong("quantity", 0L))) + .onSuccess(rows -> ctx.response().setStatusCode(201) + .putHeader("content-type", "application/json") + .end(new JsonObject() + .put("id", rows.iterator().next().getLong("id")) + .put("name", body.getValue("name")) + .put("category", body.getValue("category")) + .put("price", body.getValue("price")) + .put("quantity", body.getValue("quantity")) + .encode())) + .onFailure(e -> dbError(ctx, "insert failed", 500)); + } + + // Cache-aside on Redis where the harness provides it - crud is the one profile that + // does, and the cache is shared across every verticle instance. + private void crudRead(RoutingContext ctx) { + if (pgPool == null) { + dbError(ctx, "DB not available", 500); + return; + } + long id; + try { + id = Long.parseLong(ctx.pathParam("id")); + } catch (NumberFormatException e) { + ctx.response().setStatusCode(404).end(); + return; + } + String key = "crud:" + id; + if (redis == null) { + crudReadFromDb(ctx, id, key); + return; + } + redis.get(key) + .onSuccess(hit -> { + if (hit != null) { + ctx.response() + .putHeader("content-type", "application/json") + .putHeader("x-cache", "HIT") + .end(hit.toString()); + } else { + crudReadFromDb(ctx, id, key); + } + }) + .onFailure(e -> crudReadFromDb(ctx, id, key)); + } + + private void crudReadFromDb(RoutingContext ctx, long id, String key) { + pgPool.preparedQuery("SELECT " + ITEM_COLUMNS + " FROM items WHERE id = $1 LIMIT 1") + .execute(Tuple.of(id)) + .onSuccess(rows -> { + if (rows.size() == 0) { + ctx.response().setStatusCode(404).end(); + return; + } + String body = itemShape(rows.iterator().next()).encode(); + if (redis != null) { + redis.set(List.of(key, body, "PX", CRUD_TTL_MS)); + } + ctx.response() + .putHeader("content-type", "application/json") + .putHeader("x-cache", "MISS") + .end(body); + }) + .onFailure(e -> dbError(ctx, "query failed", 500)); + } + + private void crudUpdate(RoutingContext ctx) { + if (pgPool == null) { + dbError(ctx, "DB not available", 500); + return; + } + long id; + try { + id = Long.parseLong(ctx.pathParam("id")); + } catch (NumberFormatException e) { + ctx.response().setStatusCode(404).end(); + return; + } + JsonObject body = ctx.body().asJsonObject(); + if (body == null) { + dbError(ctx, "update failed", 500); + return; + } + long finalId = id; + pgPool.preparedQuery("UPDATE items SET name = $1, price = $2, quantity = $3 WHERE id = $4") + .execute(Tuple.of( + body.getString("name", "Updated"), + body.getLong("price", 0L), + body.getLong("quantity", 0L), + id)) + .onSuccess(rows -> { + if (rows.rowCount() == 0) { + ctx.response().setStatusCode(404).end(); + return; + } + if (redis != null) { + redis.del(List.of("crud:" + finalId)); + } + json(ctx, new JsonObject() + .put("id", finalId) + .put("name", body.getValue("name")) + .put("price", body.getValue("price")) + .put("quantity", body.getValue("quantity")) + .encode()); + }) + .onFailure(e -> dbError(ctx, "update failed", 500)); + } + private void upload(RoutingContext ctx) { HttpServerRequest request = ctx.request(); long[] size = {0}; From c34deff0b168a5d374342a8cf66d5619e4c2e729 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 21 Aug 2026 23:33:59 +0000 Subject: [PATCH 2/2] Benchmark results: vertx [skip ci] --- site/data/results/vertx.json | 423 ++++++++++++++++----- site/static/logs/api-16/1024/vertx.log | 0 site/static/logs/api-4/256/vertx.log | 0 site/static/logs/async-db/1024/vertx.log | 0 site/static/logs/crud/4096/vertx.log | 0 site/static/logs/json-tls/4096/vertx.log | 0 site/static/logs/static-tls/1024/vertx.log | 0 site/static/logs/static-tls/4096/vertx.log | 0 site/static/logs/static-tls/6800/vertx.log | 0 site/static/logs/static/1024/vertx.log | 0 site/static/logs/static/4096/vertx.log | 0 site/static/logs/static/6800/vertx.log | 0 12 files changed, 324 insertions(+), 99 deletions(-) create mode 100644 site/static/logs/api-16/1024/vertx.log create mode 100644 site/static/logs/api-4/256/vertx.log create mode 100644 site/static/logs/async-db/1024/vertx.log create mode 100644 site/static/logs/crud/4096/vertx.log create mode 100644 site/static/logs/json-tls/4096/vertx.log create mode 100644 site/static/logs/static-tls/1024/vertx.log create mode 100644 site/static/logs/static-tls/4096/vertx.log create mode 100644 site/static/logs/static-tls/6800/vertx.log create mode 100644 site/static/logs/static/1024/vertx.log create mode 100644 site/static/logs/static/4096/vertx.log create mode 100644 site/static/logs/static/6800/vertx.log diff --git a/site/data/results/vertx.json b/site/data/results/vertx.json index a31cad606..70cc18f31 100644 --- a/site/data/results/vertx.json +++ b/site/data/results/vertx.json @@ -1,22 +1,94 @@ { "framework": "vertx", "results": { + "api-16-1024": { + "framework": "vertx", + "language": "Java", + "rps": 104880, + "avg_latency": "8.31ms", + "p99_latency": "84.30ms", + "cpu": "1580.4%", + "memory": "2.0GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "524.16MB/s", + "input_bw": "5.90MB/s", + "reconnects": 314499, + "status_2xx": 1573208, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0, + "tpl_baseline": 588640, + "tpl_json": 590836, + "tpl_db": 0, + "tpl_upload": 0, + "tpl_static": 0, + "tpl_async_db": 393731 + }, + "api-4-256": { + "framework": "vertx", + "language": "Java", + "rps": 29786, + "avg_latency": "7.76ms", + "p99_latency": "92.40ms", + "cpu": "396.3%", + "memory": "618MiB", + "connections": 256, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "148.70MB/s", + "input_bw": "1.68MB/s", + "reconnects": 89335, + "status_2xx": 446803, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0, + "tpl_baseline": 167473, + "tpl_json": 167233, + "tpl_db": 0, + "tpl_upload": 0, + "tpl_static": 0, + "tpl_async_db": 112097 + }, + "async-db-1024": { + "framework": "vertx", + "language": "Java", + "rps": 198525, + "avg_latency": "4.72ms", + "p99_latency": "47.00ms", + "cpu": "4772.4%", + "memory": "5.1GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "750.36MB/s", + "input_bw": "13.25MB/s", + "reconnects": 79391, + "status_2xx": 1985254, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, "baseline-4096": { "framework": "vertx", "language": "Java", - "rps": 2060804, - "avg_latency": "1.99ms", - "p99_latency": "5.03ms", - "cpu": "6246.7%", - "memory": "4.5GiB", + "rps": 1994369, + "avg_latency": "2.06ms", + "p99_latency": "5.07ms", + "cpu": "6290.9%", + "memory": "4.8GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "129.68MB/s", - "input_bw": "159.19MB/s", + "bandwidth": "125.50MB/s", + "input_bw": "154.06MB/s", "reconnects": 0, - "status_2xx": 10304024, + "status_2xx": 9971849, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -24,19 +96,39 @@ "baseline-512": { "framework": "vertx", "language": "Java", - "rps": 2072254, - "avg_latency": "246us", - "p99_latency": "460us", - "cpu": "6418.1%", - "memory": "3.3GiB", + "rps": 2042479, + "avg_latency": "250us", + "p99_latency": "468us", + "cpu": "6487.6%", + "memory": "2.8GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "130.39MB/s", - "input_bw": "160.08MB/s", + "bandwidth": "128.53MB/s", + "input_bw": "157.78MB/s", "reconnects": 0, - "status_2xx": 10361272, + "status_2xx": 10212399, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "crud-4096": { + "framework": "vertx", + "language": "Java", + "rps": 226986, + "avg_latency": "18.03ms", + "p99_latency": "62.80ms", + "cpu": "4087.6%", + "memory": "2.9GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "64.18MB/s", + "input_bw": "19.48MB/s", + "reconnects": 15028, + "status_2xx": 3404796, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -44,19 +136,19 @@ "json-4096": { "framework": "vertx", "language": "Java", - "rps": 688783, - "avg_latency": "5.66ms", - "p99_latency": "22.90ms", - "cpu": "6242.5%", - "memory": "11.4GiB", + "rps": 671315, + "avg_latency": "5.80ms", + "p99_latency": "29.90ms", + "cpu": "6382.1%", + "memory": "6.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.30GB/s", - "input_bw": "32.84MB/s", - "reconnects": 135929, - "status_2xx": 3443915, + "bandwidth": "2.25GB/s", + "input_bw": "32.01MB/s", + "reconnects": 132671, + "status_2xx": 3356579, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -64,19 +156,19 @@ "json-comp-16384": { "framework": "vertx", "language": "Java", - "rps": 256936, - "avg_latency": "63.14ms", - "p99_latency": "149.40ms", - "cpu": "6245.0%", - "memory": "12.8GiB", + "rps": 256570, + "avg_latency": "63.01ms", + "p99_latency": "146.90ms", + "cpu": "6181.9%", + "memory": "15.2GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "330.58MB/s", - "input_bw": "19.11MB/s", - "reconnects": 44713, - "status_2xx": 1284683, + "bandwidth": "330.20MB/s", + "input_bw": "19.09MB/s", + "reconnects": 44005, + "status_2xx": 1282851, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -84,19 +176,19 @@ "json-comp-4096": { "framework": "vertx", "language": "Java", - "rps": 259189, - "avg_latency": "15.78ms", - "p99_latency": "43.40ms", - "cpu": "5997.8%", - "memory": "6.7GiB", + "rps": 256544, + "avg_latency": "15.94ms", + "p99_latency": "45.40ms", + "cpu": "6095.9%", + "memory": "6.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "333.51MB/s", - "input_bw": "19.28MB/s", - "reconnects": 50044, - "status_2xx": 1295945, + "bandwidth": "330.08MB/s", + "input_bw": "19.08MB/s", + "reconnects": 49511, + "status_2xx": 1282722, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -104,19 +196,38 @@ "json-comp-512": { "framework": "vertx", "language": "Java", - "rps": 259837, - "avg_latency": "1.97ms", - "p99_latency": "8.95ms", - "cpu": "6166.2%", + "rps": 257543, + "avg_latency": "1.98ms", + "p99_latency": "8.92ms", + "cpu": "6182.5%", "memory": "4.1GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "334.34MB/s", - "input_bw": "19.33MB/s", - "reconnects": 51952, - "status_2xx": 1299185, + "bandwidth": "331.36MB/s", + "input_bw": "19.16MB/s", + "reconnects": 51502, + "status_2xx": 1287716, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "json-tls-4096": { + "framework": "vertx", + "language": "Java", + "rps": 601618, + "avg_latency": "7.37ms", + "p99_latency": "134.88ms", + "cpu": "6181.7%", + "memory": "8.0GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "2.01GB", + "reconnects": 0, + "status_2xx": 3067146, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -124,19 +235,19 @@ "limited-conn-4096": { "framework": "vertx", "language": "Java", - "rps": 605570, - "avg_latency": "6.71ms", - "p99_latency": "68.60ms", - "cpu": "3343.8%", - "memory": "2.3GiB", + "rps": 602586, + "avg_latency": "6.77ms", + "p99_latency": "68.70ms", + "cpu": "3254.6%", + "memory": "2.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "38.10MB/s", - "input_bw": "46.78MB/s", - "reconnects": 302831, - "status_2xx": 3027853, + "bandwidth": "37.92MB/s", + "input_bw": "46.55MB/s", + "reconnects": 301293, + "status_2xx": 3012933, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -144,19 +255,19 @@ "limited-conn-512": { "framework": "vertx", "language": "Java", - "rps": 600428, - "avg_latency": "845us", - "p99_latency": "8.29ms", - "cpu": "3301.4%", + "rps": 583157, + "avg_latency": "870us", + "p99_latency": "8.54ms", + "cpu": "3191.5%", "memory": "2.4GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "37.78MB/s", - "input_bw": "46.38MB/s", - "reconnects": 300212, - "status_2xx": 3002141, + "bandwidth": "36.69MB/s", + "input_bw": "45.05MB/s", + "reconnects": 291584, + "status_2xx": 2915789, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -164,18 +275,18 @@ "pipelined-4096": { "framework": "vertx", "language": "Java", - "rps": 11211420, - "avg_latency": "5.86ms", - "p99_latency": "14.60ms", - "cpu": "6099.4%", - "memory": "6.2GiB", + "rps": 11782768, + "avg_latency": "5.58ms", + "p99_latency": "13.40ms", + "cpu": "6288.8%", + "memory": "7.3GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "705.50MB/s", + "bandwidth": "741.43MB/s", "reconnects": 0, - "status_2xx": 56057104, + "status_2xx": 58913840, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -183,18 +294,132 @@ "pipelined-512": { "framework": "vertx", "language": "Java", - "rps": 11418576, - "avg_latency": "716us", - "p99_latency": "3.60ms", - "cpu": "6154.3%", - "memory": "5.7GiB", + "rps": 12414412, + "avg_latency": "659us", + "p99_latency": "3.55ms", + "cpu": "6192.5%", + "memory": "5.2GiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "718.53MB/s", + "bandwidth": "781.18MB/s", + "reconnects": 0, + "status_2xx": 62072064, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-1024": { + "framework": "vertx", + "language": "Java", + "rps": 230227, + "avg_latency": "4.51ms", + "p99_latency": "43.67ms", + "cpu": "6447.1%", + "memory": "2.8GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "3.51GB", + "reconnects": 0, + "status_2xx": 1174059, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-4096": { + "framework": "vertx", + "language": "Java", + "rps": 227767, + "avg_latency": "17.96ms", + "p99_latency": "96.37ms", + "cpu": "6441.7%", + "memory": "3.1GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "3.48GB", + "reconnects": 0, + "status_2xx": 1161592, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-6800": { + "framework": "vertx", + "language": "Java", + "rps": 226617, + "avg_latency": "29.86ms", + "p99_latency": "148.10ms", + "cpu": "6321.8%", + "memory": "3.2GiB", + "connections": 6800, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "3.46GB", + "reconnects": 0, + "status_2xx": 1155791, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-tls-1024": { + "framework": "vertx", + "language": "Java", + "rps": 195103, + "avg_latency": "5.40ms", + "p99_latency": "49.58ms", + "cpu": "6204.9%", + "memory": "1.6GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "2.98GB", + "reconnects": 0, + "status_2xx": 994981, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-tls-4096": { + "framework": "vertx", + "language": "Java", + "rps": 191689, + "avg_latency": "21.44ms", + "p99_latency": "183.98ms", + "cpu": "6313.9%", + "memory": "3.4GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "2.93GB", + "reconnects": 0, + "status_2xx": 977503, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-tls-6800": { + "framework": "vertx", + "language": "Java", + "rps": 187031, + "avg_latency": "36.14ms", + "p99_latency": "235.22ms", + "cpu": "6282.1%", + "memory": "2.8GiB", + "connections": 6800, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "2.85GB", "reconnects": 0, - "status_2xx": 57092880, + "status_2xx": 953524, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -202,19 +427,19 @@ "upload-256": { "framework": "vertx", "language": "Java", - "rps": 2029, - "avg_latency": "122.87ms", - "p99_latency": "680.90ms", - "cpu": "6011.4%", - "memory": "8.9GiB", + "rps": 2148, + "avg_latency": "116.81ms", + "p99_latency": "683.80ms", + "cpu": "6072.8%", + "memory": "9.7GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "141.20KB/s", - "input_bw": "16.09GB/s", - "reconnects": 1982, - "status_2xx": 10145, + "bandwidth": "149.50KB/s", + "input_bw": "17.04GB/s", + "reconnects": 2110, + "status_2xx": 10744, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -222,19 +447,19 @@ "upload-32": { "framework": "vertx", "language": "Java", - "rps": 2105, - "avg_latency": "15.17ms", - "p99_latency": "62.10ms", - "cpu": "2628.5%", + "rps": 1846, + "avg_latency": "17.30ms", + "p99_latency": "73.30ms", + "cpu": "2664.8%", "memory": "7.8GiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "146.41KB/s", - "input_bw": "16.70GB/s", - "reconnects": 2106, - "status_2xx": 10525, + "bandwidth": "128.43KB/s", + "input_bw": "14.64GB/s", + "reconnects": 1846, + "status_2xx": 9233, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 diff --git a/site/static/logs/api-16/1024/vertx.log b/site/static/logs/api-16/1024/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/api-4/256/vertx.log b/site/static/logs/api-4/256/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/async-db/1024/vertx.log b/site/static/logs/async-db/1024/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/crud/4096/vertx.log b/site/static/logs/crud/4096/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/json-tls/4096/vertx.log b/site/static/logs/json-tls/4096/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/static-tls/1024/vertx.log b/site/static/logs/static-tls/1024/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/static-tls/4096/vertx.log b/site/static/logs/static-tls/4096/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/static-tls/6800/vertx.log b/site/static/logs/static-tls/6800/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/static/1024/vertx.log b/site/static/logs/static/1024/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/static/4096/vertx.log b/site/static/logs/static/4096/vertx.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/static/6800/vertx.log b/site/static/logs/static/6800/vertx.log new file mode 100644 index 000000000..e69de29bb