Skip to content

[C#] Add minima-sync - synchronous io_uring HTTP/1.1 (NativeAOT)#824

Merged
MDA2AV merged 1 commit into
mainfrom
add-minima-sync
Jun 7, 2026
Merged

[C#] Add minima-sync - synchronous io_uring HTTP/1.1 (NativeAOT)#824
MDA2AV merged 1 commit into
mainfrom
add-minima-sync

Conversation

@MDA2AV
Copy link
Copy Markdown
Owner

@MDA2AV MDA2AV commented Jun 6, 2026

Description

A synchronous single-issuer io_uring HTTP/1.1 server — the maximum-performance adaptation of Minima toward zeemo's architecture. engine-tier, baseline/pipelined/limited-conn/json. It reuses Minima's io_uring bindings (Native.cs/Ring.cs, SINGLE_ISSUER | DEFER_TASKRUN) but replaces the async engine with a zeemo-style synchronous reactor, and is NativeAOT-compiled.

Design (every choice for max throughput on CPU-bound HTTP)

  • Synchronous single-issuer reactor — recv → parse → serialize → send, all inline on the reactor thread. No async/IValueTaskSource, no MPSC queues, no eventfd — with a synchronous handler there's never an off-reactor caller, so it's pure single-issuer.
  • One pinned reactor thread per core (sched_setaffinity), own ring + own SO_REUSEPORT listener.
  • Multishot accept; single-shot recv into a per-connection buffer, parse-in-place (not multishot+provided-buffers — that's double-edged; this is zeemo's proven-fastest shape).
  • Responses serialized straight into the connection's send buffer (no managed→native copy); recv/send alternate.
  • Zero hot-path allocation — pooled connections + native (NativeMemory) recv/write buffers.
  • NativeAOT — native binary, no .NET runtime/JIT warmup (closes most of the managed-runtime gap to native).
  • JSON serialized per request from the parsed model.

vs minima

minima is the general async engine (keeps async-db/crud capability). minima-sync trades that away — a synchronous reactor blocks the core on any slow handler — for raw throughput on the CPU-only profiles. So it's a separate entry.

Tests

baseline, pipelined, limited-conn, json. Verified against the full contract (GET/CL/chunked sum, /pipeline, 16× pipelining, keep-alive, fragmented reads, Connection: close, 200-connection churn, json count + total = price*quantity*m for 12/22/31/50) under JIT and as the NativeAOT container.

io_uring needs seccomp=unconfined; engine: "io_uring" makes validate.sh enable it.

A synchronous single-issuer io_uring server built on Minima's io_uring
bindings (Native.cs/Ring.cs) with zeemo's reactor architecture, for maximum
throughput on the H1-isolated profiles: one pinned reactor thread per core
(SO_REUSEPORT, SINGLE_ISSUER|DEFER_TASKRUN), multishot accept + single-shot
recv into per-connection buffers (parse-in-place), responses serialized
straight into the send buffer, recv/send alternating fully inline. No
async/IValueTaskSource, no MPSC queues, no eventfd; zero hot-path
allocation. NativeAOT-compiled (native binary, no .NET runtime). JSON
serialized per request from the model.

Subscribes to baseline, pipelined, limited-conn, json. Verified against the
full contract (sum/CL/chunked, pipeline, keep-alive, fragmented reads,
connection churn, json count/total) under JIT and as the NativeAOT container.
@MDA2AV MDA2AV force-pushed the add-minima-sync branch from 28b0b16 to f47ea26 Compare June 6, 2026 17:40
@MDA2AV
Copy link
Copy Markdown
Owner Author

MDA2AV commented Jun 6, 2026

/benchmark -f minima-sync

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

👋 /benchmark request received. A collaborator will review and approve the run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

Benchmark Results

Framework: minima-sync | Test: all tests

Test Conn RPS CPU Mem Δ RPS Δ Mem
baseline 512 4,219,355 6326.9% 83MiB NEW NEW
baseline 4096 4,440,585 6225.4% 132MiB NEW NEW
pipelined 512 55,097,606 6337.8% 81MiB NEW NEW
pipelined 4096 58,034,656 6400.5% 145MiB NEW NEW
limited-conn 512 2,691,611 5406.9% 99MiB NEW NEW
limited-conn 4096 2,712,650 5768.0% 183MiB NEW NEW
json 4096 2,375,785 6462.3% 230MiB NEW NEW
Full log
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  10
  Templates: 3
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   1.40ms   1.37ms   1.66ms   1.85ms   3.37ms

  13408050 requests in 5.00s, 13408430 responses
  Throughput: 2.68M req/s
  Bandwidth:  168.71MB/s
  Status codes: 2xx=13408430, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 13408430 / 13408430 responses (100.0%)
  Reconnects: 1339200
  Per-template: 4469423,4469785,4469222
  Per-template-ok: 4469423,4469785,4469222
[info] CPU 5506.3% | Mem 179MiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  10
  Templates: 3
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   1.37ms   1.35ms   1.67ms   1.88ms   2.25ms

  13563819 requests in 5.00s, 13563251 responses
  Throughput: 2.71M req/s
  Bandwidth:  170.67MB/s
  Status codes: 2xx=13563251, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 13563223 / 13563251 responses (100.0%)
  Reconnects: 1356845
  Per-template: 4521178,4521042,4521003
  Per-template-ok: 4521178,4521042,4521003
[info] CPU 5768.0% | Mem 183MiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  10
  Templates: 3
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   1.37ms   1.36ms   1.67ms   1.88ms   2.22ms

  13509842 requests in 5.00s, 13510030 responses
  Throughput: 2.70M req/s
  Bandwidth:  170.00MB/s
  Status codes: 2xx=13510030, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 13509890 / 13510030 responses (100.0%)
  Reconnects: 1350836
  Per-template: 4503154,4503557,4503179
  Per-template-ok: 4503154,4503557,4503179
[info] CPU 5627.9% | Mem 183MiB

=== Best: 2712650 req/s (CPU: 5768.0%, Mem: 183MiB) ===
[info] input BW: 209.55MB/s (avg template: 81 bytes)
[info] saved results/limited-conn/4096/minima-sync.json
httparena-bench-minima-sync
httparena-bench-minima-sync

==============================================
=== minima-sync / json / 4096c (tool=gcannon) ===
==============================================
[info] waiting for server...
[info] server ready

[run 1/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  25
  Templates: 7
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    856us    437us   2.31ms   3.35ms   4.38ms

  11771947 requests in 5.00s, 11771762 responses
  Throughput: 2.35M req/s
  Bandwidth:  7.88GB/s
  Status codes: 2xx=11771762, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 11771762 / 11771762 responses (100.0%)
  Reconnects: 468969
  Per-template: 1675413,1678971,1682613,1686636,1687293,1683831,1677005
  Per-template-ok: 1675413,1678971,1682613,1686636,1687293,1683831,1677005
[info] CPU 6100.1% | Mem 220MiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  25
  Templates: 7
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    809us    426us   2.25ms   3.22ms   3.85ms

  11879161 requests in 5.00s, 11878929 responses
  Throughput: 2.38M req/s
  Bandwidth:  7.96GB/s
  Status codes: 2xx=11878929, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 11878911 / 11878929 responses (100.0%)
  Reconnects: 474889
  Per-template: 1690518,1694453,1698457,1701827,1702343,1698212,1693101
  Per-template-ok: 1690518,1694453,1698457,1701827,1702343,1698212,1693101
[info] CPU 6462.3% | Mem 230MiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  25
  Templates: 7
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency    805us    422us   2.23ms   3.23ms   3.96ms

  11820449 requests in 5.00s, 11820436 responses
  Throughput: 2.36M req/s
  Bandwidth:  7.92GB/s
  Status codes: 2xx=11820436, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 11822759 / 11820436 responses (100.0%)
  Reconnects: 473665
  Per-template: 1682100,1686139,1690196,1694467,1693855,1690177,1683409
  Per-template-ok: 1682100,1686139,1690196,1694467,1693855,1690177,1683409
[info] CPU 6205.0% | Mem 234MiB

=== Best: 2375785 req/s (CPU: 6462.3%, Mem: 230MiB) ===
[info] input BW: 113.29MB/s (avg template: 50 bytes)
[info] saved results/json/4096/minima-sync.json
httparena-bench-minima-sync
httparena-bench-minima-sync
[info] skip: minima-sync does not subscribe to json-comp
[info] skip: minima-sync does not subscribe to json-tls
[info] skip: minima-sync does not subscribe to upload
[info] skip: minima-sync does not subscribe to api-4
[info] skip: minima-sync does not subscribe to api-16
[info] skip: minima-sync does not subscribe to static
[info] skip: minima-sync does not subscribe to async-db
[info] skip: minima-sync does not subscribe to crud
[info] skip: minima-sync does not subscribe to fortunes
[info] skip: minima-sync does not subscribe to baseline-h2
[info] skip: minima-sync does not subscribe to static-h2
[info] skip: minima-sync does not subscribe to baseline-h2c
[info] skip: minima-sync does not subscribe to json-h2c
[info] skip: minima-sync does not subscribe to baseline-h3
[info] skip: minima-sync does not subscribe to static-h3
[info] skip: minima-sync does not subscribe to gateway-64
[info] skip: minima-sync does not subscribe to gateway-h3
[info] skip: minima-sync does not subscribe to production-stack
[info] skip: minima-sync does not subscribe to unary-grpc
[info] skip: minima-sync does not subscribe to unary-grpc-tls
[info] skip: minima-sync does not subscribe to stream-grpc
[info] skip: minima-sync does not subscribe to stream-grpc-tls
[info] skip: minima-sync does not subscribe to echo-ws
[info] skip: minima-sync does not subscribe to echo-ws-pipeline
[info] rebuilding site/data/*.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/baseline-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/baseline-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/limited-conn-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/limited-conn-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/pipelined-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/pipelined-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
[info] restoring loopback MTU to 65536

@MDA2AV
Copy link
Copy Markdown
Owner Author

MDA2AV commented Jun 6, 2026

/benchmark -f minima-sync --save

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

👋 /benchmark request received. A collaborator will review and approve the run.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

⚠️ /benchmark --save cannot start: main has diverged and cannot be auto-merged into this branch. Please merge or rebase main manually, push, and re-run /benchmark --save.

@MDA2AV MDA2AV merged commit f3b6abb into main Jun 7, 2026
4 checks passed
@MDA2AV MDA2AV deleted the add-minima-sync branch June 7, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant