Skip to content

Commit 2b0aa70

Browse files
Zix 0.4.x rc3 http (#885)
* bump to zix 0.4.x-rc3 for http test * swithing to io_uring. * updating description that reflecting zix approach * Benchmark results: zix --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent a44baf8 commit 2b0aa70

17 files changed

Lines changed: 122 additions & 113 deletions

frameworks/zix/Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ARG RETRY=6
55
ARG TARGETARCH
66
ARG RETRY_DELAY=3
77
ARG ZIG_VERSION=0.16.0
8-
ARG ZIX_VERSION=0.4.x
8+
ARG ZIX_VERSION=0.4.x-rc3
99
RUN apk add --no-cache ca-certificates curl git tar xz
1010

1111
RUN set -eu; \
@@ -19,9 +19,9 @@ RUN set -eu; \
1919
mv "/opt/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}" /opt/zig
2020
ENV PATH="/opt/zig:${PATH}"
2121

22-
# Vendor zix 0.4.x, separate layer so source-only rebuilds skip the fetch.
22+
# Vendor zix X.Y.Z, separate layer so source-only rebuilds skip the fetch.
2323
# The Http1 raw engine work this image needs (large-body drain plus the per-worker
24-
# response cache used by the /json endpoint) must be present on the 0.4.x branch.
24+
# response cache used by the /json endpoint) must be present on the X.Y.Z branch.
2525
# Four ordered attempts before giving up: curl the archive tarball from github then
2626
# codeberg, then a shallow git clone from github then codeberg. The github archive
2727
# redirects to codeload.github.com (which the benchmark runner may not resolve), so

frameworks/zix/meta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"language": "Zig",
44
"type": "engine",
55
"engine": "zix",
6-
"description": "Zig HTTP/1.1 server on the zix.Http1 raw engine (no std.http). Shared-nothing: each worker runs its own SO_REUSEPORT accept plus level-triggered epoll loop and owns its connections. The /json endpoint serves from the per-worker response cache, and request bodies larger than the read buffer are drained rather than buffered.",
6+
"description": "Zig HTTP/1.1 server on the zix.Http1 raw engine (no std.http). Shared-nothing: each worker runs its own SO_REUSEPORT multishot accept plus io_uring completion loop and owns its connections. The /json endpoint serves from the per-worker response cache, and request bodies larger than the read buffer are drained rather than buffered.",
77
"repo": "https://github.com/prothegee/zix",
88
"enabled": true,
99
"tests": [

frameworks/zix/src/dataset.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//! HttpArena: zix
2-
//! zix version: 0.4.x
32
//!
43
//! Dataset loader for the /json endpoint.
54
//!

frameworks/zix/src/main.zig

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
//! HttpArena: zix
2-
//! zix version: 0.4.x
32
//!
43
//! zix HttpArena HTTP/1.1 entry point.
54
//!
6-
//! Intent: demonstrate zix.Http1 (URING dispatch model) against the HttpArena
5+
//! Intent: demonstrate zix.Http1 (EPOLL dispatch model) against the HttpArena
76
//! HTTP/1.1 benchmark suite (baseline, pipelined, short-lived).
87
//!
98
//! Design choices:
10-
//! - rawIntercept: called before any header parsing for each URING request.
9+
//! - rawIntercept: called before any header parsing for each EPOLL request.
1110
//! Handles /pipeline with zero parse overhead (direct byte-match + sink write),
1211
//! direct byte-match before any parsing, avoiding the header scan loop. Routes that fall
1312
//! through are handled by the Router dispatch with full parsing.
@@ -23,14 +22,25 @@ const dataset = @import("dataset.zig");
2322

2423
const PORT: u16 = 8080;
2524
const LISTEN_IP: []const u8 = "::";
26-
const DISPATCH_MODEL: zix.Http1.DispatchModel = .EPOLL;
25+
const DISPATCH_MODEL: zix.Http1.DispatchModel = .URING;
2726
const KERNEL_BACKLOG: u31 = 16 * 1024;
28-
/// 4 KiB per-connection recv buffer (heap-allocated once at accept time).
29-
/// Benchmark requests are under 300 bytes. Halving from 16 KiB cuts the
30-
/// working set from 64 MiB to 16 MiB at 4096c, reducing cache pressure.
31-
/// Large upload bodies are drained by the engine in chunks, so headers
32-
/// (always < 4 KiB) are the only part that needs to fit.
33-
const MAX_RECV_BUF: usize = 4 * 1024;
27+
/// Per-machine tuning profile (ADR-041 increment 5). The dev box is 12 threads
28+
/// / 32 GB (lean, memory-bound), the competition box is 64 cores / 251 GB
29+
/// (throughput, RAM-abundant). Only the recv buffer differs: workers auto-scale
30+
/// (WORKERS = 0), and the backlog and cache are already sized for both. Select
31+
/// .throughput for the 64-core deployment.
32+
const Profile = enum { lean, throughput };
33+
const PROFILE: Profile = .lean;
34+
35+
/// Per-connection recv buffer, heap-allocated once at accept time. .lean keeps
36+
/// 4 KiB to hold the working set small (benchmark requests are under 300 bytes,
37+
/// and large upload bodies are drained by the engine in chunks, so only headers,
38+
/// always < 4 KiB, must fit). .throughput raises it to 16 KiB for deeper
39+
/// pipelined batches per recv, which the RAM-abundant box absorbs.
40+
const MAX_RECV_BUF: usize = switch (PROFILE) {
41+
.lean => 4 * 1024,
42+
.throughput => 16 * 1024,
43+
};
3444
const MAX_HEADERS: u8 = 16;
3545
const WORKERS: usize = 0;
3646

@@ -99,7 +109,7 @@ fn pipelineHandler(head: *const zix.Http1.ParsedHead, body: []const u8, fd: std.
99109
zix.Http1.fdWriteAll(fd, PIPELINE_RESP) catch {};
100110
}
101111

102-
// Raw-request interceptor for the URING dispatch model. Called before any header
112+
// Raw-request interceptor for the EPOLL dispatch model. Called before any header
103113
// parsing on each inbound request. Handles /pipeline with zero parse overhead:
104114
// byte-matches the path directly on rem, then appends PIPELINE_RESP to the
105115
// coalescing RespSink. Unknown

site/data/baseline-4096.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,19 +1627,19 @@
16271627
{
16281628
"framework": "zix",
16291629
"language": "Zig",
1630-
"rps": 3654683,
1631-
"avg_latency": "1.12ms",
1632-
"p99_latency": "2.36ms",
1633-
"cpu": "6610.8%",
1634-
"memory": "395MiB",
1630+
"rps": 4492613,
1631+
"avg_latency": "911us",
1632+
"p99_latency": "1.19ms",
1633+
"cpu": "6413.1%",
1634+
"memory": "186MiB",
16351635
"connections": 4096,
16361636
"threads": 64,
16371637
"duration": "5s",
16381638
"pipeline": 1,
1639-
"bandwidth": "229.97MB/s",
1640-
"input_bw": "282.32MB/s",
1639+
"bandwidth": "282.68MB/s",
1640+
"input_bw": "347.04MB/s",
16411641
"reconnects": 0,
1642-
"status_2xx": 18273419,
1642+
"status_2xx": 22463065,
16431643
"status_3xx": 0,
16441644
"status_4xx": 0,
16451645
"status_5xx": 0

site/data/baseline-512.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,19 +1627,19 @@
16271627
{
16281628
"framework": "zix",
16291629
"language": "Zig",
1630-
"rps": 3670251,
1631-
"avg_latency": "138us",
1632-
"p99_latency": "371us",
1633-
"cpu": "6426.7%",
1634-
"memory": "342MiB",
1630+
"rps": 4217982,
1631+
"avg_latency": "120us",
1632+
"p99_latency": "231us",
1633+
"cpu": "6348.6%",
1634+
"memory": "130MiB",
16351635
"connections": 512,
16361636
"threads": 64,
16371637
"duration": "5s",
16381638
"pipeline": 1,
1639-
"bandwidth": "230.95MB/s",
1640-
"input_bw": "283.52MB/s",
1639+
"bandwidth": "265.42MB/s",
1640+
"input_bw": "325.83MB/s",
16411641
"reconnects": 0,
1642-
"status_2xx": 18351256,
1642+
"status_2xx": 21089911,
16431643
"status_3xx": 0,
16441644
"status_4xx": 0,
16451645
"status_5xx": 0

site/data/frameworks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@
915915
},
916916
"zix": {
917917
"dir": "zix",
918-
"description": "Zig HTTP/1.1 server on the zix.Http1 raw engine (no std.http). Shared-nothing: each worker runs its own SO_REUSEPORT accept plus level-triggered epoll loop and owns its connections. The /json endpoint serves from the per-worker response cache, and request bodies larger than the read buffer are drained rather than buffered.",
918+
"description": "Zig HTTP/1.1 server on the zix.Http1 raw engine (no std.http). Shared-nothing: each worker runs its own SO_REUSEPORT multishot accept plus io_uring completion loop and owns its connections. The /json endpoint serves from the per-worker response cache, and request bodies larger than the read buffer are drained rather than buffered.",
919919
"repo": "https://github.com/prothegee/zix",
920920
"type": "engine",
921921
"engine": "zix"

site/data/json-4096.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,19 +1375,19 @@
13751375
{
13761376
"framework": "zix",
13771377
"language": "Zig",
1378-
"rps": 2396373,
1379-
"avg_latency": "865us",
1380-
"p99_latency": "3.70ms",
1381-
"cpu": "6464.5%",
1382-
"memory": "1.2GiB",
1378+
"rps": 2348626,
1379+
"avg_latency": "614us",
1380+
"p99_latency": "2.75ms",
1381+
"cpu": "5365.1%",
1382+
"memory": "290MiB",
13831383
"connections": 4096,
13841384
"threads": 64,
13851385
"duration": "5s",
13861386
"pipeline": 1,
1387-
"bandwidth": "8.02GB/s",
1388-
"input_bw": "114.27MB/s",
1389-
"reconnects": 478596,
1390-
"status_2xx": 11981868,
1387+
"bandwidth": "7.86GB/s",
1388+
"input_bw": "111.99MB/s",
1389+
"reconnects": 468990,
1390+
"status_2xx": 11743130,
13911391
"status_3xx": 0,
13921392
"status_4xx": 0,
13931393
"status_5xx": 0

site/data/limited-conn-4096.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,19 +1627,19 @@
16271627
{
16281628
"framework": "zix",
16291629
"language": "Zig",
1630-
"rps": 2748274,
1631-
"avg_latency": "1.38ms",
1632-
"p99_latency": "2.75ms",
1633-
"cpu": "6224.6%",
1634-
"memory": "1.5GiB",
1630+
"rps": 2751069,
1631+
"avg_latency": "1.35ms",
1632+
"p99_latency": "1.89ms",
1633+
"cpu": "5783.9%",
1634+
"memory": "237MiB",
16351635
"connections": 4096,
16361636
"threads": 64,
16371637
"duration": "5s",
16381638
"pipeline": 1,
1639-
"bandwidth": "172.91MB/s",
1640-
"input_bw": "212.30MB/s",
1641-
"reconnects": 1374498,
1642-
"status_2xx": 13741371,
1639+
"bandwidth": "173.09MB/s",
1640+
"input_bw": "212.51MB/s",
1641+
"reconnects": 1375655,
1642+
"status_2xx": 13755345,
16431643
"status_3xx": 0,
16441644
"status_4xx": 0,
16451645
"status_5xx": 0

site/data/limited-conn-512.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,19 +1627,19 @@
16271627
{
16281628
"framework": "zix",
16291629
"language": "Zig",
1630-
"rps": 2535229,
1631-
"avg_latency": "187us",
1632-
"p99_latency": "687us",
1633-
"cpu": "5722.1%",
1634-
"memory": "482MiB",
1630+
"rps": 2740199,
1631+
"avg_latency": "170us",
1632+
"p99_latency": "403us",
1633+
"cpu": "5474.7%",
1634+
"memory": "150MiB",
16351635
"connections": 512,
16361636
"threads": 64,
16371637
"duration": "5s",
16381638
"pipeline": 1,
1639-
"bandwidth": "159.53MB/s",
1640-
"input_bw": "195.84MB/s",
1641-
"reconnects": 1267619,
1642-
"status_2xx": 12676149,
1639+
"bandwidth": "172.36MB/s",
1640+
"input_bw": "211.67MB/s",
1641+
"reconnects": 1369714,
1642+
"status_2xx": 13700995,
16431643
"status_3xx": 0,
16441644
"status_4xx": 0,
16451645
"status_5xx": 0

0 commit comments

Comments
 (0)