diff --git a/frameworks/oxpecker/Dockerfile b/frameworks/oxpecker/Dockerfile index 3b09c0c8f..39daa0a16 100644 --- a/frameworks/oxpecker/Dockerfile +++ b/frameworks/oxpecker/Dockerfile @@ -1,6 +1,10 @@ FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /app -COPY . . +COPY frameworks/oxpecker/ . +# Drop any host build output that came along with the copy; the SDK image has +# to restore for linux-x64 itself. +RUN rm -rf bin obj + RUN dotnet publish -c Release -o out FROM mcr.microsoft.com/dotnet/aspnet:10.0 diff --git a/frameworks/oxpecker/Handlers.fs b/frameworks/oxpecker/Handlers.fs index 6d42ce7a7..c2b4cdda5 100644 --- a/frameworks/oxpecker/Handlers.fs +++ b/frameworks/oxpecker/Handlers.fs @@ -5,11 +5,8 @@ open System.Buffers open System.Globalization open System.IO open System.Text - open HttpArena.Services - open Microsoft.AspNetCore.Http - open Oxpecker /// Reads an int query parameter through Oxpecker's query accessor, falling @@ -20,8 +17,7 @@ let private queryInt (ctx: HttpContext) (key: string) (fallback: int) = match Int32.TryParse(raw, NumberStyles.Integer, CultureInfo.InvariantCulture) with | true, value -> value | _ -> fallback - | None -> - fallback + | None -> fallback let private queryFloat (ctx: HttpContext) (key: string) (fallback: float) = match ctx.TryGetQueryValue key with @@ -31,10 +27,6 @@ let private queryFloat (ctx: HttpContext) (key: string) (fallback: float) = | _ -> fallback | None -> fallback -let private dbUnavailable (ctx: HttpContext) = - ctx.SetStatusCode 500 - ctx.WriteText "DB not available" - // ── Connection profiles ──────────────────────────────────────────────────── let pipeline: EndpointHandler = text "ok" @@ -55,6 +47,7 @@ let baselineWithBody: EndpointHandler = task { use reader = new StreamReader(ctx.Request.Body) let! body = reader.ReadToEndAsync() + let fromBody = match Int32.TryParse(body, NumberStyles.Integer, CultureInfo.InvariantCulture) with | true, value -> value @@ -91,103 +84,82 @@ let upload: EndpointHandler = let json (count: int) : EndpointHandler = fun ctx -> let multiplier = queryInt ctx "m" 1 - match Dataset.getItems count multiplier with - | Some response -> - ctx.WriteJsonChunked response - | None -> - ctx.SetStatusCode 500 - ctx.WriteText "Dataset not loaded" + let response = Dataset.getItems count multiplier + ctx.WriteJsonChunked response // ── Database profiles ────────────────────────────────────────────────────── /// GET /async-db — Postgres range query over the unindexed price column. let asyncDb: EndpointHandler = fun ctx -> - if not Items.isAvailable then - dbUnavailable ctx - else - let minPrice = queryFloat ctx "min" 10.0 - let maxPrice = queryFloat ctx "max" 50.0 - let limit = queryInt ctx "limit" 50 - task { - let! response = Items.query minPrice maxPrice limit - return! ctx.WriteJsonChunked response - } + let minPrice = queryFloat ctx "min" 10.0 + let maxPrice = queryFloat ctx "max" 50.0 + let limit = queryInt ctx "limit" 50 + task { + let! response = Items.query minPrice maxPrice limit + return! ctx.WriteJsonChunked response + } /// GET /crud/items — paginated list by category. let crudList: EndpointHandler = fun ctx -> - if not Items.isAvailable then - dbUnavailable ctx - else - let category = ctx.TryGetQueryValue "category" |> Option.defaultValue "" - let page = queryInt ctx "page" 0 - let limit = queryInt ctx "limit" 0 - task { - let! response = Items.list category page limit - return! ctx.WriteJsonChunked response - } + let category = ctx.TryGetQueryValue "category" |> Option.defaultValue "" + let page = queryInt ctx "page" 0 + let limit = queryInt ctx "limit" 0 + task { + let! response = Items.list category page limit + return! ctx.WriteJsonChunked response + } /// GET /crud/items/{id} — cache-aside single-item read, reporting the cache /// outcome through X-Cache. let crudRead (id: int) : EndpointHandler = fun ctx -> - if not Items.isAvailable then - dbUnavailable ctx - else - task { - match! Items.read id with - | None -> - ctx.SetStatusCode 404 - | Some result -> - ctx.SetHttpHeader("X-Cache", (if result.CacheHit then "HIT" else "MISS")) - match result.Value with - | TypedItem item -> - return! ctx.WriteJson item - | SerializedItem cached -> - // Already JSON on the Redis path — write the cached bytes - // back rather than round-tripping them through the serializer. - ctx.SetContentType "application/json; charset=utf-8" - return! ctx.WriteBytes(Encoding.UTF8.GetBytes cached) - } + task { + match! Items.read id with + | ValueNone -> + ctx.SetStatusCode 404 + | ValueSome result -> + ctx.SetHttpHeader("X-Cache", if result.CacheHit then "HIT" else "MISS") + match result.Value with + | TypedItem item -> + return! ctx.WriteJsonChunked item + | SerializedItem cached -> + // Already JSON on the Redis path — write the cached bytes + // back rather than round-tripping them through the serializer. + ctx.SetContentType "application/json" + return! ctx.WriteBytes(Encoding.UTF8.GetBytes cached) + } /// POST /crud/items — create (upsert on id conflict). let crudCreate: EndpointHandler = fun ctx -> - if not Items.isAvailable then - dbUnavailable ctx - else - task { - let! input = ctx.BindJson() - let! created = Items.create input - ctx.SetStatusCode 201 - return! ctx.WriteJson created - } + task { + let! input = ctx.BindJson() + let! created = Items.create input + ctx.SetStatusCode 201 + return! ctx.WriteJsonChunked created + } /// PUT /crud/items/{id} — update and invalidate the cached entry. let crudUpdate (id: int) : EndpointHandler = fun ctx -> - if not Items.isAvailable then - dbUnavailable ctx - else - task { - let! input = ctx.BindJson() - match! Items.update id input with - | None -> - ctx.SetStatusCode 404 - | Some updated -> - return! ctx.WriteJson updated - } + task { + let! input = ctx.BindJson() + match! Items.update id input with + | None -> + ctx.SetStatusCode 404 + | Some updated -> + return! ctx.WriteJsonChunked updated + } + // ── Template profile ─────────────────────────────────────────────────────── /// GET /fortunes — DB query plus an Oxpecker.ViewEngine render. let fortunes: EndpointHandler = fun ctx -> - if not Items.isAvailable then - dbUnavailable ctx - else - task { - let! rows = Fortunes.getRows () - return! ctx.WriteHtmlViewChunked(Views.fortunes rows) - } + task { + let! rows = Fortunes.getRows () + return! ctx.WriteHtmlViewChunked(Views.fortunes rows) + } diff --git a/frameworks/oxpecker/HttpArena.Oxpecker.fsproj b/frameworks/oxpecker/HttpArena.Oxpecker.fsproj index 4f336f2dc..45bde5424 100644 --- a/frameworks/oxpecker/HttpArena.Oxpecker.fsproj +++ b/frameworks/oxpecker/HttpArena.Oxpecker.fsproj @@ -3,7 +3,6 @@ net10.0 true - false @@ -18,8 +17,7 @@ - - + diff --git a/frameworks/oxpecker/Program.fs b/frameworks/oxpecker/Program.fs index 8b6a3eec3..19e62e65f 100644 --- a/frameworks/oxpecker/Program.fs +++ b/frameworks/oxpecker/Program.fs @@ -3,20 +3,15 @@ module HttpArena.Program open System open System.IO open System.Security.Cryptography.X509Certificates -open System.Threading.Tasks - -open HttpArena.Services - open Microsoft.AspNetCore.Builder open Microsoft.AspNetCore.Hosting open Microsoft.AspNetCore.Http open Microsoft.AspNetCore.Server.Kestrel.Core +open Microsoft.AspNetCore.StaticFiles open Microsoft.Extensions.DependencyInjection open Microsoft.Extensions.FileProviders open Microsoft.Extensions.Hosting open Microsoft.Extensions.Logging -open Microsoft.Extensions.Primitives - open Oxpecker @@ -100,36 +95,35 @@ let main args = let app = builder.Build() - // The Services modules hold their state in module-level bindings, which - // .NET initializes on first touch. Reading them here loads the dataset and - // opens the Postgres/Redis pools at startup instead of during the first - // request — and turns a missing dataset or DATABASE_URL into a startup - // message rather than mystery 500s. - if not Dataset.isAvailable then - Console.Error.WriteLine "dataset not loaded; /json will answer 500" - - if not Database.isAvailable then - Console.Error.WriteLine "DATABASE_URL not configured; DB endpoints will answer 500" - app.UseResponseCompression() |> ignore - // Static assets are served straight off the mounted directory by ASP.NET - // Core's static file middleware — every request reads the file from disk, - // and the response compression middleware above handles the compressible - // types. Registered before routing so /static/* never reaches Oxpecker, - // while a missing file falls through to the router's 404. - let staticRoot = envPath "STATIC_PATH" "/data/static" - - if Directory.Exists staticRoot then - app.UseStaticFiles( - StaticFileOptions( - FileProvider = new PhysicalFileProvider(staticRoot), - RequestPath = PathString "/static" - ) + // Served straight out of the directory the profile mounts, rather than a + // copy taken at image build. MapStaticAssets, which this used before, + // resolves assets through a manifest the SDK generates at publish time from + // wwwroot, so the container held two copies of the corpus and answered from + // the one the harness cannot touch: replacing a file in the mounted + // directory never reached a response. + // + // UseStaticFiles reads the file per request through the file provider, so + // what is served follows the mounted directory. Compression stays with the + // response compression middleware registered above. + let staticContentTypes = FileExtensionContentTypeProvider() + staticContentTypes.Mappings[".webp"] <- "image/webp" + staticContentTypes.Mappings[".woff2"] <- "font/woff2" + + app.UseStaticFiles( + StaticFileOptions( + FileProvider = new PhysicalFileProvider("/data/static"), + RequestPath = PathString "/static", + ContentTypeProvider = staticContentTypes, + ServeUnknownFileTypes = false ) - |> ignore + ) + |> ignore + + app.UseRouting() |> ignore - app.UseRouting().UseOxpecker(endpoints) |> ignore + app.UseOxpecker endpoints |> ignore app.Run() 0 diff --git a/frameworks/oxpecker/README.md b/frameworks/oxpecker/README.md index cf5c2b2a0..3851c9441 100644 --- a/frameworks/oxpecker/README.md +++ b/frameworks/oxpecker/README.md @@ -25,7 +25,7 @@ F# web framework built on ASP.NET Core endpoint routing, running on .NET 10 with | `/crud/items` | POST | Create item via INSERT with ON CONFLICT upsert, returns 201 | | `/crud/items/{id}` | PUT | Update item and invalidate cache entry | | `/fortunes` | GET | DB query + HTML table rendered with Oxpecker.ViewEngine | -| `/static/*` | GET | Serves files from `/data/static` via ASP.NET Core's static file middleware | +| `/static/*` | GET | Serves the static assets straight from the mounted `/data/static` | ## Notes @@ -36,7 +36,8 @@ F# web framework built on ASP.NET Core endpoint routing, running on .NET 10 with - HTTP/1.1 on port 8080, HTTP/1+2+3 on port 8443 (TCP **and** UDP for QUIC), h1+TLS on 8081, prior-knowledge h2c on 8082 - TLS certs from `$TLS_CERT` / `$TLS_KEY` (default `/certs/server.crt` + `/certs/server.key`); TLS listeners skipped when absent - HTTP/2 tuned: 256 max streams per connection, 2 MB initial connection window, 1 MB stream window -- `AddResponseCompression()` + `UseResponseCompression()` for `json-comp`; `UseStaticFiles` reads static bodies from disk on every request +- `AddResponseCompression()` + `UseResponseCompression()` for `json-comp` +- `UseStaticFiles` for `/static/*` with a `PhysicalFileProvider` on `/data/static`, so what is served follows the directory the harness mounts rather than a build-time copy in `wwwroot` (see #1268); `.webp` and `.woff2` are added to the content type provider, and compression is left to the response compression middleware - `/upload` drains the body through a 64 KB pooled buffer (`ArrayPool.Shared`) - Postgres pooled via `NpgsqlDataSource` with auto-prepare; crud read cache is Redis when `REDIS_URL` is set, else in-process `MemoryCache` - Logging disabled (`ClearProviders()`); `ServerGarbageCollection` enabled diff --git a/frameworks/oxpecker/Services/Database.fs b/frameworks/oxpecker/Services/Database.fs index ad3338ca3..e028c5cea 100644 --- a/frameworks/oxpecker/Services/Database.fs +++ b/frameworks/oxpecker/Services/Database.fs @@ -65,9 +65,5 @@ let postgres = openPostgres () /// uses Redis as a shared cache; otherwise it uses an in-process MemoryCache. let redis = openRedis () -/// True once the Postgres pool is configured; the DB-backed endpoints answer -/// 500 without it. -let isAvailable = postgres.IsSome - -/// Opens a pooled command. Only valid once `isAvailable` is true. +/// Opens a pooled command. let command (sql: string) = postgres.Value.CreateCommand sql diff --git a/frameworks/oxpecker/Services/Dataset.fs b/frameworks/oxpecker/Services/Dataset.fs index fad1a553f..489aabe7b 100644 --- a/frameworks/oxpecker/Services/Dataset.fs +++ b/frameworks/oxpecker/Services/Dataset.fs @@ -15,33 +15,26 @@ let private items = | value -> value if File.Exists path then - JsonSerializer.Deserialize(File.ReadAllText path, Serialization.options) |> Some + JsonSerializer.Deserialize(File.ReadAllText path, Serialization.options) else - None + null -let isAvailable = items.IsSome - -/// Returns the first `count` dataset items with their total computed as -/// price * quantity * `multiplier`, or None when no dataset is loaded. let getItems (count: int) (multiplier: int) = - match items with - | None -> None - | Some source -> - let count = Math.Clamp(count, 0, source.Length) - let processed = Array.zeroCreate count - - for i in 0 .. count - 1 do - let item = source[i] - processed[i] <- { - Id = item.Id - Name = item.Name - Category = item.Category - Price = item.Price - Quantity = item.Quantity - Active = item.Active - Tags = item.Tags - Rating = item.Rating - Total = int64 item.Price * int64 item.Quantity * int64 multiplier - } - - Some { Items = processed; Count = count } + let count = Math.Clamp(count, 0, items.Length) + let processed = Array.zeroCreate count + + for i in 0 .. count - 1 do + let item = items[i] + processed[i] <- { + Id = item.Id + Name = item.Name + Category = item.Category + Price = item.Price + Quantity = item.Quantity + Active = item.Active + Tags = item.Tags + Rating = item.Rating + Total = item.Price * item.Quantity * multiplier + } + + { JsonResponse.Items = processed; Count = count } diff --git a/frameworks/oxpecker/Services/Fortunes.fs b/frameworks/oxpecker/Services/Fortunes.fs index bb4743858..c3457c874 100644 --- a/frameworks/oxpecker/Services/Fortunes.fs +++ b/frameworks/oxpecker/Services/Fortunes.fs @@ -3,9 +3,13 @@ module HttpArena.Services.Fortunes open System +open System.Collections.Generic open HttpArena -let isAvailable = Database.isAvailable +let FortuneComparer = { + new IComparer with + member self.Compare(a,b) = String.CompareOrdinal(a.Message, b.Message) +} let getRows () = task { @@ -20,7 +24,7 @@ let getRows () = // Runtime-injected row defeats whole-page memoization: the rendered // HTML must vary per request, even though the seeded rows don't. rows.Add { Id = 0; Message = "Additional fortune added at request time." } - rows.Sort(fun a b -> String.CompareOrdinal(a.Message, b.Message)) + rows.Sort(FortuneComparer) return rows } diff --git a/frameworks/oxpecker/Services/Items.fs b/frameworks/oxpecker/Services/Items.fs index 6c935c057..4569d36af 100644 --- a/frameworks/oxpecker/Services/Items.fs +++ b/frameworks/oxpecker/Services/Items.fs @@ -77,10 +77,8 @@ module private Cache = /// In-process fallback; only constructed when Redis is not configured. let local = match Database.redis with - | Some _ -> None - | None -> Some(new MemoryCache(MemoryCacheOptions())) - -let isAvailable = Database.isAvailable + | Some _ -> ValueNone + | None -> ValueSome(new MemoryCache(MemoryCacheOptions())) let private fetchById (id: int) = task { @@ -88,7 +86,7 @@ let private fetchById (id: int) = cmd.Parameters.Add(intParameter id) |> ignore use! reader = cmd.ExecuteReaderAsync() let! hasRow = reader.ReadAsync() - return if hasRow then Some(Sql.read reader) else None + return if hasRow then ValueSome(Sql.read reader) else ValueNone } /// Range query for /async-db: items with price between `minPrice` and `maxPrice`. @@ -107,7 +105,7 @@ let query (minPrice: float) (maxPrice: float) (limit: int) = while! reader.ReadAsync() do items.Add(Sql.read reader) - return { Items = items.ToArray(); Count = items.Count } + return { Items = items; Count = items.Count } } /// Paginated list by category (always DB, never cached). Out-of-range paging @@ -131,8 +129,8 @@ let list (category: string) (page: int) (limit: int) = items.Add(Sql.read reader) return { - Items = items.ToArray() - Total = int64 items.Count + Items = items + Total = items.Count Page = page Limit = limit } @@ -150,23 +148,23 @@ let read (id: int) = | Some redis -> match! redis.StringGetAsync(RedisKey key) with | cached when cached.HasValue -> - return Some { Value = SerializedItem(cached.ToString()); CacheHit = true } + return ValueSome { Value = SerializedItem(cached.ToString()); CacheHit = true } | _ -> match! fetchById id with - | None -> return None - | Some item -> + | ValueNone -> return ValueNone + | ValueSome item -> let json = JsonSerializer.Serialize(item, Serialization.options) let! _ = redis.StringSetAsync(RedisKey key, RedisValue json, Nullable Cache.ttl, When.Always) - return Some { Value = SerializedItem json; CacheHit = false } + return ValueSome { Value = SerializedItem json; CacheHit = false } | None -> match Cache.local.Value.TryGetValue key with - | true, (:? Item as item) -> return Some { Value = TypedItem item; CacheHit = true } + | true, (:? Item as item) -> return ValueSome { Value = TypedItem item; CacheHit = true } | _ -> match! fetchById id with - | None -> return None - | Some item -> + | ValueNone -> return ValueNone + | ValueSome item -> Cache.local.Value.Set(key, item, Cache.entryOptions) |> ignore - return Some { Value = TypedItem item; CacheHit = false } + return ValueSome { Value = TypedItem item; CacheHit = false } } /// Creates an item (upsert on id conflict). @@ -182,7 +180,7 @@ let create (input: CrudItemInput) = let! newId = cmd.ExecuteScalarAsync() return { - Id = Convert.ToInt32 newId + Id = unbox newId Name = input.Name Category = input.Category Price = input.Price @@ -205,12 +203,11 @@ let update (id: int) (input: CrudItemInput) = if affected = 0 then return None else - do! - match Database.redis with - | Some redis -> redis.KeyDeleteAsync(RedisKey(Cache.key id)) :> Task - | None -> - Cache.local.Value.Remove(Cache.key id) - Task.CompletedTask + match Database.redis with + | Some redis -> + do! redis.KeyDeleteAsync(RedisKey(Cache.key id)) :> Task + | None -> + Cache.local.Value.Remove(Cache.key id) return Some { diff --git a/frameworks/oxpecker/Types.fs b/frameworks/oxpecker/Types.fs index 615d89f54..187e2a4aa 100644 --- a/frameworks/oxpecker/Types.fs +++ b/frameworks/oxpecker/Types.fs @@ -30,10 +30,18 @@ type ProcessedItem = { Active: bool Tags: string[] Rating: RatingInfo - Total: int64 + Total: int } -type ItemsResponse<'T> = { Items: 'T[]; Count: int } +type JsonResponse = { + Items: ProcessedItem[] + Count: int +} + +type AsyncDbResponse = { + Items: ResizeArray + Count: int +} /// Request body of POST /crud/items and PUT /crud/items/{id}. Fields the /// caller omits (PUT never sends an id) stay at their default. @@ -47,8 +55,8 @@ type CrudItemInput = { } type CrudListResponse = { - Items: Item[] - Total: int64 + Items: ResizeArray + Total: int Page: int Limit: int } @@ -64,10 +72,12 @@ type CrudWriteResponse = { /// Payload of a cached single-item read. The two cache backends hand back /// different shapes: the in-process cache stores the typed DTO, Redis stores /// the already-serialized JSON so a HIT skips a Deserialize+Serialize round trip. +[] type CachedItem = - | TypedItem of Item - | SerializedItem of string + | TypedItem of item:Item + | SerializedItem of json:string +[] type CachedItemResult = { Value: CachedItem; CacheHit: bool } type Fortune = { Id: int; Message: string } diff --git a/frameworks/oxpecker/Views.fs b/frameworks/oxpecker/Views.fs index e801c8aa9..e91e11b68 100644 --- a/frameworks/oxpecker/Views.fs +++ b/frameworks/oxpecker/Views.fs @@ -2,33 +2,31 @@ module HttpArena.Views open Oxpecker.ViewEngine - -let private pageHead = - head () { - title () { "Fortunes" } - } - -let private tableHead = - thead () { - tr () { - th () { "id" } - th () { "message" } +let private layout = + prerenderAround (fun content -> + html () { + head () { + title () { "Fortunes" } + } + body () { + table () { + thead () { + tr () { + th () { "id" } + th () { "message" } + } + } + content + } + } } - } + ) let fortunes (rows: ResizeArray) = - html () { - pageHead - - body () { - table () { - tableHead - - for row in rows do - tr () { - td () { row.Id } - td () { row.Message } - } + layout() { + for row in rows do + tr () { + td () { row.Id } + td () { row.Message } } - } } diff --git a/frameworks/oxpecker/build.sh b/frameworks/oxpecker/build.sh new file mode 100755 index 000000000..5de8892df --- /dev/null +++ b/frameworks/oxpecker/build.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" +docker build -t httparena-oxpecker -f "$SCRIPT_DIR/Dockerfile" "$ROOT_DIR" diff --git a/site/data/results/oxpecker.json b/site/data/results/oxpecker.json index 664c19ca8..58853f76c 100644 --- a/site/data/results/oxpecker.json +++ b/site/data/results/oxpecker.json @@ -4,71 +4,71 @@ "api-16-1024": { "framework": "oxpecker", "language": "F#", - "rps": 105416, - "avg_latency": "7.06ms", - "p99_latency": "18.40ms", - "cpu": "1463.8%", - "memory": "249MiB", + "rps": 106273, + "avg_latency": "6.93ms", + "p99_latency": "17.70ms", + "cpu": "1467.2%", + "memory": "221MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "533.52MB/s", - "input_bw": "5.93MB/s", - "reconnects": 316295, - "status_2xx": 1581245, + "bandwidth": "537.62MB/s", + "input_bw": "5.98MB/s", + "reconnects": 318756, + "status_2xx": 1594099, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 592594, - "tpl_json": 593570, + "tpl_baseline": 597823, + "tpl_json": 598145, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 395081 + "tpl_async_db": 398129 }, "api-4-256": { "framework": "oxpecker", "language": "F#", - "rps": 34987, - "avg_latency": "5.33ms", - "p99_latency": "11.60ms", - "cpu": "381.0%", - "memory": "133MiB", + "rps": 35594, + "avg_latency": "5.16ms", + "p99_latency": "11.20ms", + "cpu": "385.6%", + "memory": "134MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "176.90MB/s", - "input_bw": "1.97MB/s", - "reconnects": 104976, - "status_2xx": 524805, + "bandwidth": "179.98MB/s", + "input_bw": "2.00MB/s", + "reconnects": 106793, + "status_2xx": 533922, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 196991, - "tpl_json": 196809, + "tpl_baseline": 200381, + "tpl_json": 200283, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 131005 + "tpl_async_db": 133257 }, "async-db-1024": { "framework": "oxpecker", "language": "F#", - "rps": 184664, - "avg_latency": "4.92ms", - "p99_latency": "19.70ms", - "cpu": "4442.4%", - "memory": "390MiB", + "rps": 190861, + "avg_latency": "4.76ms", + "p99_latency": "19.40ms", + "cpu": "4556.9%", + "memory": "383MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "711.03MB/s", - "input_bw": "12.33MB/s", - "reconnects": 73687, - "status_2xx": 1846644, + "bandwidth": "734.82MB/s", + "input_bw": "12.74MB/s", + "reconnects": 76267, + "status_2xx": 1908615, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -76,19 +76,19 @@ "baseline-4096": { "framework": "oxpecker", "language": "F#", - "rps": 1433634, - "avg_latency": "2.12ms", - "p99_latency": "7.40ms", - "cpu": "5541.7%", - "memory": "349MiB", + "rps": 1444879, + "avg_latency": "2.38ms", + "p99_latency": "7.51ms", + "cpu": "5621.0%", + "memory": "320MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "161.29MB/s", - "input_bw": "110.74MB/s", + "bandwidth": "162.56MB/s", + "input_bw": "111.61MB/s", "reconnects": 0, - "status_2xx": 7168174, + "status_2xx": 7224399, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -96,19 +96,19 @@ "baseline-512": { "framework": "oxpecker", "language": "F#", - "rps": 1404010, - "avg_latency": "364us", - "p99_latency": "1.66ms", - "cpu": "5001.3%", - "memory": "218MiB", + "rps": 1410285, + "avg_latency": "362us", + "p99_latency": "1.57ms", + "cpu": "5010.3%", + "memory": "214MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "157.96MB/s", - "input_bw": "108.46MB/s", + "bandwidth": "158.67MB/s", + "input_bw": "108.94MB/s", "reconnects": 0, - "status_2xx": 7020052, + "status_2xx": 7051428, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -116,18 +116,18 @@ "baseline-h2-1024": { "framework": "oxpecker", "language": "F#", - "rps": 2640805, - "avg_latency": "36.92ms", - "p99_latency": "178.71ms", - "cpu": "5910.3%", - "memory": "2.9GiB", + "rps": 2676309, + "avg_latency": "37.67ms", + "p99_latency": "187.30ms", + "cpu": "6246.5%", + "memory": "2.3GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "68.87MB/s", + "bandwidth": "69.80MB/s", "reconnects": 0, - "status_2xx": 13362477, + "status_2xx": 13542127, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -135,18 +135,18 @@ "baseline-h2-256": { "framework": "oxpecker", "language": "F#", - "rps": 2705299, - "avg_latency": "8.91ms", - "p99_latency": "63.03ms", - "cpu": "6166.3%", + "rps": 2720556, + "avg_latency": "8.82ms", + "p99_latency": "52.01ms", + "cpu": "6203.0%", "memory": "1.1GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "70.23MB/s", + "bandwidth": "70.63MB/s", "reconnects": 0, - "status_2xx": 13634709, + "status_2xx": 13711606, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -154,18 +154,18 @@ "baseline-h2c-1024": { "framework": "oxpecker", "language": "F#", - "rps": 3262496, - "avg_latency": "33.00ms", - "p99_latency": "189.67ms", - "cpu": "6009.5%", + "rps": 3329815, + "avg_latency": "32.45ms", + "p99_latency": "174.99ms", + "cpu": "6332.1%", "memory": "2.7GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "82.08MB/s", + "bandwidth": "83.60MB/s", "reconnects": 0, - "status_2xx": 16540857, + "status_2xx": 16848868, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -173,18 +173,18 @@ "baseline-h2c-256": { "framework": "oxpecker", "language": "F#", - "rps": 3492011, - "avg_latency": "7.44ms", - "p99_latency": "54.40ms", - "cpu": "6316.9%", - "memory": "1014MiB", + "rps": 3280460, + "avg_latency": "7.79ms", + "p99_latency": "46.52ms", + "cpu": "6384.2%", + "memory": "1.2GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "87.12MB/s", + "bandwidth": "81.85MB/s", "reconnects": 0, - "status_2xx": 17564818, + "status_2xx": 16500714, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -192,18 +192,18 @@ "baseline-h2c-4096": { "framework": "oxpecker", "language": "F#", - "rps": 2866558, - "avg_latency": "114.15ms", - "p99_latency": "411.82ms", - "cpu": "5865.1%", - "memory": "6.6GiB", + "rps": 2399981, + "avg_latency": "133.28ms", + "p99_latency": "547.10ms", + "cpu": "4657.9%", + "memory": "6.2GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "72.65MB/s", + "bandwidth": "60.85MB/s", "reconnects": 0, - "status_2xx": 14619449, + "status_2xx": 12239905, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -211,18 +211,18 @@ "baseline-h3-64": { "framework": "oxpecker", "language": "F#", - "rps": 664769, - "avg_latency": "5.65ms", - "p99_latency": "17.80ms", - "cpu": "5986.0%", + "rps": 606148, + "avg_latency": "6.52ms", + "p99_latency": "25.79ms", + "cpu": "6141.3%", "memory": "1.2GiB", "connections": 64, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "59.71MB/s", + "bandwidth": "54.45MB/s", "reconnects": 0, - "status_2xx": 3330497, + "status_2xx": 3036803, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -230,19 +230,19 @@ "crud-4096": { "framework": "oxpecker", "language": "F#", - "rps": 362342, - "avg_latency": "10.46ms", - "p99_latency": "30.40ms", - "cpu": "5566.6%", - "memory": "432MiB", + "rps": 365178, + "avg_latency": "10.60ms", + "p99_latency": "33.20ms", + "cpu": "5274.0%", + "memory": "419MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "120.30MB/s", - "input_bw": "31.10MB/s", - "reconnects": 25170, - "status_2xx": 5435139, + "bandwidth": "119.15MB/s", + "input_bw": "31.34MB/s", + "reconnects": 25489, + "status_2xx": 5477676, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -250,18 +250,18 @@ "fortunes-1024": { "framework": "oxpecker", "language": "F#", - "rps": 73397, - "avg_latency": "11.50ms", - "p99_latency": "30.90ms", - "cpu": "5475.8%", - "memory": "414MiB", + "rps": 74459, + "avg_latency": "11.13ms", + "p99_latency": "30.20ms", + "cpu": "5555.1%", + "memory": "428MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.70GB/s", + "bandwidth": "1.72GB/s", "reconnects": 0, - "status_2xx": 366989, + "status_2xx": 372298, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -269,19 +269,19 @@ "json-4096": { "framework": "oxpecker", "language": "F#", - "rps": 632245, - "avg_latency": "4.41ms", - "p99_latency": "19.60ms", - "cpu": "5881.4%", - "memory": "463MiB", + "rps": 629531, + "avg_latency": "3.92ms", + "p99_latency": "21.60ms", + "cpu": "5921.4%", + "memory": "431MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.16GB/s", - "input_bw": "30.15MB/s", - "reconnects": 125069, - "status_2xx": 3161228, + "bandwidth": "2.15GB/s", + "input_bw": "30.02MB/s", + "reconnects": 124362, + "status_2xx": 3147656, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -289,19 +289,19 @@ "json-comp-16384": { "framework": "oxpecker", "language": "F#", - "rps": 351320, - "avg_latency": "15.01ms", - "p99_latency": "44.10ms", - "cpu": "5770.8%", - "memory": "596MiB", + "rps": 362467, + "avg_latency": "15.29ms", + "p99_latency": "52.20ms", + "cpu": "5833.5%", + "memory": "636MiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "668.93MB/s", - "input_bw": "26.13MB/s", - "reconnects": 67239, - "status_2xx": 1756600, + "bandwidth": "690.08MB/s", + "input_bw": "26.96MB/s", + "reconnects": 69217, + "status_2xx": 1812337, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -309,19 +309,19 @@ "json-comp-4096": { "framework": "oxpecker", "language": "F#", - "rps": 355534, - "avg_latency": "9.02ms", - "p99_latency": "33.20ms", - "cpu": "5897.5%", - "memory": "522MiB", + "rps": 365828, + "avg_latency": "8.97ms", + "p99_latency": "32.10ms", + "cpu": "5874.9%", + "memory": "501MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "676.98MB/s", - "input_bw": "26.45MB/s", - "reconnects": 69371, - "status_2xx": 1777673, + "bandwidth": "696.48MB/s", + "input_bw": "27.21MB/s", + "reconnects": 71490, + "status_2xx": 1829144, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -329,19 +329,19 @@ "json-comp-512": { "framework": "oxpecker", "language": "F#", - "rps": 364379, - "avg_latency": "1.38ms", - "p99_latency": "6.68ms", - "cpu": "5545.4%", - "memory": "251MiB", + "rps": 369192, + "avg_latency": "1.37ms", + "p99_latency": "6.66ms", + "cpu": "5570.4%", + "memory": "252MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "693.78MB/s", - "input_bw": "27.10MB/s", - "reconnects": 72886, - "status_2xx": 1821896, + "bandwidth": "702.97MB/s", + "input_bw": "27.46MB/s", + "reconnects": 73817, + "status_2xx": 1845960, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -349,18 +349,18 @@ "json-h2c-1024": { "framework": "oxpecker", "language": "F#", - "rps": 850740, - "avg_latency": "38.23ms", - "p99_latency": "233.94ms", - "cpu": "6160.9%", - "memory": "2.1GiB", + "rps": 841533, + "avg_latency": "39.24ms", + "p99_latency": "174.64ms", + "cpu": "6168.3%", + "memory": "1.9GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.85GB/s", + "bandwidth": "2.81GB/s", "reconnects": 0, - "status_2xx": 4313255, + "status_2xx": 4258159, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -368,18 +368,18 @@ "json-h2c-4096": { "framework": "oxpecker", "language": "F#", - "rps": 725010, - "avg_latency": "150.77ms", - "p99_latency": "825.24ms", - "cpu": "5910.2%", + "rps": 702233, + "avg_latency": "142.50ms", + "p99_latency": "846.14ms", + "cpu": "5755.2%", "memory": "4.1GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.43GB/s", + "bandwidth": "2.36GB/s", "reconnects": 0, - "status_2xx": 3683051, + "status_2xx": 3581389, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -387,18 +387,18 @@ "json-tls-4096": { "framework": "oxpecker", "language": "F#", - "rps": 543639, - "avg_latency": "7.77ms", - "p99_latency": "106.94ms", - "cpu": "6233.3%", - "memory": "650MiB", + "rps": 549249, + "avg_latency": "7.61ms", + "p99_latency": "66.02ms", + "cpu": "6090.2%", + "memory": "862MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.86GB", + "bandwidth": "1.88GB", "reconnects": 0, - "status_2xx": 2772115, + "status_2xx": 2801074, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -406,19 +406,19 @@ "limited-conn-4096": { "framework": "oxpecker", "language": "F#", - "rps": 461091, - "avg_latency": "1.55ms", - "p99_latency": "12.30ms", - "cpu": "3214.8%", - "memory": "127MiB", + "rps": 463184, + "avg_latency": "1.56ms", + "p99_latency": "12.40ms", + "cpu": "3142.6%", + "memory": "124MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "51.87MB/s", - "input_bw": "35.62MB/s", - "reconnects": 230546, - "status_2xx": 2305459, + "bandwidth": "52.11MB/s", + "input_bw": "35.78MB/s", + "reconnects": 231618, + "status_2xx": 2315920, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -426,19 +426,19 @@ "limited-conn-512": { "framework": "oxpecker", "language": "F#", - "rps": 451144, - "avg_latency": "1.13ms", - "p99_latency": "12.00ms", - "cpu": "3137.5%", - "memory": "123MiB", + "rps": 467843, + "avg_latency": "1.09ms", + "p99_latency": "11.70ms", + "cpu": "3360.9%", + "memory": "120MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "50.75MB/s", - "input_bw": "34.85MB/s", - "reconnects": 225565, - "status_2xx": 2255724, + "bandwidth": "52.63MB/s", + "input_bw": "36.14MB/s", + "reconnects": 233922, + "status_2xx": 2339216, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -446,18 +446,18 @@ "pipelined-4096": { "framework": "oxpecker", "language": "F#", - "rps": 14157800, - "avg_latency": "4.01ms", + "rps": 14011805, + "avg_latency": "3.80ms", "p99_latency": "11.30ms", - "cpu": "5941.0%", - "memory": "328MiB", + "cpu": "5838.6%", + "memory": "263MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "1.56GB/s", + "bandwidth": "1.54GB/s", "reconnects": 0, - "status_2xx": 70789003, + "status_2xx": 70059025, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -465,18 +465,18 @@ "pipelined-512": { "framework": "oxpecker", "language": "F#", - "rps": 13539179, - "avg_latency": "604us", - "p99_latency": "3.34ms", - "cpu": "5890.5%", - "memory": "134MiB", + "rps": 13699003, + "avg_latency": "597us", + "p99_latency": "3.28ms", + "cpu": "5914.5%", + "memory": "132MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "1.49GB/s", + "bandwidth": "1.50GB/s", "reconnects": 0, - "status_2xx": 67695898, + "status_2xx": 68495018, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -484,18 +484,18 @@ "static-1024": { "framework": "oxpecker", "language": "F#", - "rps": 117630, - "avg_latency": "8.84ms", - "p99_latency": "57.72ms", - "cpu": "6004.1%", - "memory": "396MiB", + "rps": 117660, + "avg_latency": "8.80ms", + "p99_latency": "46.99ms", + "cpu": "6007.8%", + "memory": "412MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, "bandwidth": "3.15GB", "reconnects": 0, - "status_2xx": 597400, + "status_2xx": 600016, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -503,18 +503,18 @@ "static-4096": { "framework": "oxpecker", "language": "F#", - "rps": 114841, - "avg_latency": "36.03ms", - "p99_latency": "932.48ms", - "cpu": "5999.2%", - "memory": "816MiB", + "rps": 116410, + "avg_latency": "33.64ms", + "p99_latency": "477.52ms", + "cpu": "6002.6%", + "memory": "736MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.08GB", + "bandwidth": "3.12GB", "reconnects": 0, - "status_2xx": 585643, + "status_2xx": 593750, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -522,18 +522,18 @@ "static-6800": { "framework": "oxpecker", "language": "F#", - "rps": 115378, - "avg_latency": "76.68ms", - "p99_latency": "1.89s", - "cpu": "6084.8%", - "memory": "992MiB", + "rps": 116960, + "avg_latency": "51.16ms", + "p99_latency": "578.49ms", + "cpu": "6183.3%", + "memory": "993MiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.09GB", + "bandwidth": "3.13GB", "reconnects": 0, - "status_2xx": 588712, + "status_2xx": 596559, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -541,18 +541,18 @@ "static-h2-1024": { "framework": "oxpecker", "language": "F#", - "rps": 52916, - "avg_latency": "552.45ms", - "p99_latency": "3.44s", - "cpu": "5217.1%", - "memory": "9.0GiB", + "rps": 50822, + "avg_latency": "573.61ms", + "p99_latency": "4.64s", + "cpu": "5868.3%", + "memory": "7.3GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.32GB/s", + "bandwidth": "1.23GB/s", "reconnects": 0, - "status_2xx": 267226, + "status_2xx": 257162, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -560,18 +560,18 @@ "static-h2-256": { "framework": "oxpecker", "language": "F#", - "rps": 73483, - "avg_latency": "108.49ms", - "p99_latency": "1.12s", - "cpu": "6223.4%", - "memory": "3.5GiB", + "rps": 72979, + "avg_latency": "110.06ms", + "p99_latency": "1.38s", + "cpu": "6198.2%", + "memory": "3.4GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.94GB/s", + "bandwidth": "1.92GB/s", "reconnects": 0, - "status_2xx": 369620, + "status_2xx": 367088, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -579,18 +579,18 @@ "static-h3-64": { "framework": "oxpecker", "language": "F#", - "rps": 34767, - "avg_latency": "97.81ms", - "p99_latency": "539.51ms", - "cpu": "5716.0%", + "rps": 32870, + "avg_latency": "99.79ms", + "p99_latency": "563.52ms", + "cpu": "5950.2%", "memory": "1.6GiB", "connections": 64, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "930.49MB/s", + "bandwidth": "880.27MB/s", "reconnects": 0, - "status_2xx": 174186, + "status_2xx": 164682, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -598,18 +598,18 @@ "static-tls-1024": { "framework": "oxpecker", "language": "F#", - "rps": 95443, - "avg_latency": "10.81ms", - "p99_latency": "45.31ms", - "cpu": "6088.0%", - "memory": "535MiB", + "rps": 94761, + "avg_latency": "10.89ms", + "p99_latency": "73.08ms", + "cpu": "6152.6%", + "memory": "566MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.56GB", + "bandwidth": "2.54GB", "reconnects": 0, - "status_2xx": 485318, + "status_2xx": 483253, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -617,18 +617,18 @@ "static-tls-4096": { "framework": "oxpecker", "language": "F#", - "rps": 93453, - "avg_latency": "42.32ms", - "p99_latency": "193.40ms", - "cpu": "6105.5%", + "rps": 94992, + "avg_latency": "41.72ms", + "p99_latency": "238.99ms", + "cpu": "6087.6%", "memory": "1.3GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.50GB", + "bandwidth": "2.54GB", "reconnects": 0, - "status_2xx": 476638, + "status_2xx": 484397, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -636,18 +636,18 @@ "static-tls-6800": { "framework": "oxpecker", "language": "F#", - "rps": 91710, - "avg_latency": "67.72ms", - "p99_latency": "260.17ms", - "cpu": "5996.2%", - "memory": "1.8GiB", + "rps": 91158, + "avg_latency": "72.97ms", + "p99_latency": "317.40ms", + "cpu": "5726.0%", + "memory": "2.0GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.46GB", + "bandwidth": "2.44GB", "reconnects": 0, - "status_2xx": 467718, + "status_2xx": 464896, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -655,19 +655,19 @@ "upload-256": { "framework": "oxpecker", "language": "F#", - "rps": 1542, - "avg_latency": "161.41ms", - "p99_latency": "803.40ms", - "cpu": "6415.4%", - "memory": "322MiB", + "rps": 1563, + "avg_latency": "159.38ms", + "p99_latency": "827.30ms", + "cpu": "6370.8%", + "memory": "341MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "185.65KB/s", - "input_bw": "12.23GB/s", - "reconnects": 1527, - "status_2xx": 7714, + "bandwidth": "188.09KB/s", + "input_bw": "12.40GB/s", + "reconnects": 1540, + "status_2xx": 7815, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -675,19 +675,19 @@ "upload-32": { "framework": "oxpecker", "language": "F#", - "rps": 1315, - "avg_latency": "24.45ms", - "p99_latency": "70.90ms", - "cpu": "6179.9%", - "memory": "146MiB", + "rps": 1296, + "avg_latency": "24.63ms", + "p99_latency": "66.50ms", + "cpu": "6392.3%", + "memory": "151MiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "158.29KB/s", - "input_bw": "10.43GB/s", - "reconnects": 1304, - "status_2xx": 6578, + "bandwidth": "155.95KB/s", + "input_bw": "10.28GB/s", + "reconnects": 1293, + "status_2xx": 6481, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 diff --git a/site/static/logs/baseline-h2/1024/oxpecker.log b/site/static/logs/baseline-h2/1024/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline-h2/1024/oxpecker.log +++ b/site/static/logs/baseline-h2/1024/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline-h2/256/oxpecker.log b/site/static/logs/baseline-h2/256/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline-h2/256/oxpecker.log +++ b/site/static/logs/baseline-h2/256/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline-h2c/1024/oxpecker.log b/site/static/logs/baseline-h2c/1024/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline-h2c/1024/oxpecker.log +++ b/site/static/logs/baseline-h2c/1024/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline-h2c/256/oxpecker.log b/site/static/logs/baseline-h2c/256/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline-h2c/256/oxpecker.log +++ b/site/static/logs/baseline-h2c/256/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline-h2c/4096/oxpecker.log b/site/static/logs/baseline-h2c/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline-h2c/4096/oxpecker.log +++ b/site/static/logs/baseline-h2c/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline-h3/64/oxpecker.log b/site/static/logs/baseline-h3/64/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline-h3/64/oxpecker.log +++ b/site/static/logs/baseline-h3/64/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline/4096/oxpecker.log b/site/static/logs/baseline/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline/4096/oxpecker.log +++ b/site/static/logs/baseline/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/baseline/512/oxpecker.log b/site/static/logs/baseline/512/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/baseline/512/oxpecker.log +++ b/site/static/logs/baseline/512/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json-comp/16384/oxpecker.log b/site/static/logs/json-comp/16384/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json-comp/16384/oxpecker.log +++ b/site/static/logs/json-comp/16384/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json-comp/4096/oxpecker.log b/site/static/logs/json-comp/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json-comp/4096/oxpecker.log +++ b/site/static/logs/json-comp/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json-comp/512/oxpecker.log b/site/static/logs/json-comp/512/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json-comp/512/oxpecker.log +++ b/site/static/logs/json-comp/512/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json-h2c/1024/oxpecker.log b/site/static/logs/json-h2c/1024/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json-h2c/1024/oxpecker.log +++ b/site/static/logs/json-h2c/1024/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json-h2c/4096/oxpecker.log b/site/static/logs/json-h2c/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json-h2c/4096/oxpecker.log +++ b/site/static/logs/json-h2c/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json-tls/4096/oxpecker.log b/site/static/logs/json-tls/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json-tls/4096/oxpecker.log +++ b/site/static/logs/json-tls/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/json/4096/oxpecker.log b/site/static/logs/json/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/json/4096/oxpecker.log +++ b/site/static/logs/json/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/limited-conn/4096/oxpecker.log b/site/static/logs/limited-conn/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/limited-conn/4096/oxpecker.log +++ b/site/static/logs/limited-conn/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/limited-conn/512/oxpecker.log b/site/static/logs/limited-conn/512/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/limited-conn/512/oxpecker.log +++ b/site/static/logs/limited-conn/512/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/pipelined/4096/oxpecker.log b/site/static/logs/pipelined/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/pipelined/4096/oxpecker.log +++ b/site/static/logs/pipelined/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/pipelined/512/oxpecker.log b/site/static/logs/pipelined/512/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/pipelined/512/oxpecker.log +++ b/site/static/logs/pipelined/512/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static-h2/1024/oxpecker.log b/site/static/logs/static-h2/1024/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static-h2/1024/oxpecker.log +++ b/site/static/logs/static-h2/1024/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static-h2/256/oxpecker.log b/site/static/logs/static-h2/256/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static-h2/256/oxpecker.log +++ b/site/static/logs/static-h2/256/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static-h3/64/oxpecker.log b/site/static/logs/static-h3/64/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static-h3/64/oxpecker.log +++ b/site/static/logs/static-h3/64/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static-tls/1024/oxpecker.log b/site/static/logs/static-tls/1024/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static-tls/1024/oxpecker.log +++ b/site/static/logs/static-tls/1024/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static-tls/4096/oxpecker.log b/site/static/logs/static-tls/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static-tls/4096/oxpecker.log +++ b/site/static/logs/static-tls/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static-tls/6800/oxpecker.log b/site/static/logs/static-tls/6800/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static-tls/6800/oxpecker.log +++ b/site/static/logs/static-tls/6800/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static/1024/oxpecker.log b/site/static/logs/static/1024/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static/1024/oxpecker.log +++ b/site/static/logs/static/1024/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static/4096/oxpecker.log b/site/static/logs/static/4096/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static/4096/oxpecker.log +++ b/site/static/logs/static/4096/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/static/6800/oxpecker.log b/site/static/logs/static/6800/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/static/6800/oxpecker.log +++ b/site/static/logs/static/6800/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/upload/256/oxpecker.log b/site/static/logs/upload/256/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/upload/256/oxpecker.log +++ b/site/static/logs/upload/256/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500 diff --git a/site/static/logs/upload/32/oxpecker.log b/site/static/logs/upload/32/oxpecker.log index 2d3a93b3e..e69de29bb 100644 --- a/site/static/logs/upload/32/oxpecker.log +++ b/site/static/logs/upload/32/oxpecker.log @@ -1 +0,0 @@ -DATABASE_URL not configured; DB endpoints will answer 500