Repository navigation
Conversation
|
An automated preview of the documentation is available at https://389.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-10-08 18:09:23 UTC |
|
GCOVR code coverage report https://389.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-10-08 18:21:20 UTC |
The multishot acceptor allocated a waiter_node when parking an accept and a fresh uring_accept_op at every completion boundary, copying the request fields across and deleting the waiter -- two heap round trips per accepted connection, plus a ready_fd_node whenever a delivery arrived before an accept was parked. A parked waiter and its completion have strictly sequential lifetimes, so fold them into one accept_node that is both an intrusive list node and the posted op. Nodes recycle through a per-acceptor free list via the op's new dispose hook, ready-fd nodes recycle the same way, and each in-flight node keeps the acceptor alive through the op envelope's object_ref slot. The inherited cancelled flag keeps its claim-token role; claiming paths now restore the real completion status after stop_cb.reset() quiesces any in-flight canceller. The uring zero-alloc gate pins accept churn at 0 allocations per cycle, matching epoll; only select retains its documented 2/cycle registered_descs_ cost.
Every read_some_at/write_some_at heap-allocated its op -- a deliberate choice so concurrent operations at distinct offsets can overlap, but one that cost ~500 bytes of malloc/free per call on the posix, io_uring, and IOCP backends alike. Keep the unlimited-concurrency model and recycle the ops instead: completion pushes the op onto a per-file free list (posix reuses the outstanding-ops hook and mutex; uring wraps the heap op types in a pooled subclass that swaps the completion handler; IOCP recycles raf_concurrent_op under its existing ops_mutex_). Each completion copies out what it needs before the push, since a concurrent initiation may refill the op immediately, and drops its impl keepalive only after leaving the list mutex. The storage belongs to the impl, survives impl recycling, and is freed by the impl destructor. The zero-alloc gate grows a raf churn test pinning a warmed write+read round trip at 0 allocations on every backend.
Launching a worker for an accepted connection paid three heap round trips: a fresh std::stop_source shared state, a launch_wrapper coroutine frame through the global allocator, and a wrapper op for posting the bare coroutine handle. Reuse the worker's stop_source across connections and replace it only once a stop has actually been delivered; route the launch_wrapper frame through capy's frame_alloc_mixin so the thread-local recycling allocator serves it; and post the launch through a frame-embedded capy::continuation, which the Executor concept already guarantees every executor accepts. The zero-alloc gate grows a server churn test pinning a warmed connect/echo/close round trip through tcp_server at 0 allocations (select keeps its documented 2/cycle registered_descs_ cost).
Since clang 23's static ASan runtime, the fault harness's interposed symbols bind ahead of the sanitizer's interceptors (verbosity=1 reports "failed to intercept 'pthread_create'"), so threads created through the raw libc pthread_create bypass ASan's thread registry and the first join aborts with "Joining already joined thread" -- every fault test failed instantly under local ASan builds. Sanitizers export each interceptor as __interceptor_<name> precisely so an interposer can cooperate. Under a sanitizer build, resolve the census's libc half through those exports (weak references, so a name the runtime does not intercept falls back to the RTLD_NEXT lookup unchanged). Injection semantics are untouched: shadows still run first and armed faults short-circuit before the chained call; unsanitized builds compile the mechanism away entirely.
A completion whose awaiter runs on a non-io_context executor takes dispatch_coro's deferring branch, which handed the executor the op's EMBEDDED continuation -- held on its queue by reference until dequeue (a documented stable-address contract). Every completion tail then consumes its op: recycling it into a free list (pooled uring accept/raf nodes), reusing the embedded slot on the next operation (reactor and IOCP ops), or deleting it (heap ops). A concurrent operation could therefore rewrite or free a queued node, and the dequeued resume targeted a dead or rewritten handle. Two new tests reproduce it deterministically (latch-sequenced, no timing): park a single-worker pool behind a latch so the deferred completion queues into it, refill the op from the io_context side, then release the worker. They crashed on every backend -- uring (pooled nodes), epoll/select (embedded accept op via coro_resume), and IOCP in CI (embedded accept op) -- so the fix lives at the one chokepoint every path shares: dispatch_coro's deferring branch now lends the executor a continuation owned by a self-destroying trampoline frame (post_resume; frames served by capy's recycling pool) and no longer retains the caller's. The io_context fast path is unchanged, and callers keep the uniform consume-then-resume shape since nothing they own stays queued. run_async could not serve as the trampoline: its launch wrapper calls ex.on_work_finished() after the task completes, but the op's executor_ref points into the awaiting coroutine's environment, which the resume destroys -- completions must never touch the executor after resuming the handle, and the trampoline doesn't.
Each reactor wake constructed to_add/to_cancel inside the loop, swapped away pending_register_/pending_cancel_'s capacity, and freed it at scope end -- two malloc/free per wake (pollfds beside them was already hoisted). Hoist both and clear per iteration: the capacities then ping-pong between the locals and the members through the under-lock swap, and a warmed reactor wake allocates nothing.
Vale's docstring lint reads the wrapped line's leading identifier as bare prose; rewrapping keeps the reference intact.
Benchmark report
|
| Platform | Backend | Benchmark | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|---|
| windows | iocp | accept_churn/burst/100 | ops_per_sec | 149.1 ops/s | 155.6 ops/s | 🟢▲ +4.40% | 0.93% |
| windows | iocp | accept_churn/burst_lockless/100 | ops_per_sec | 152.4 ops/s | 158.5 ops/s | 🟢▲ +3.85% | 0.64% |
| macos | kqueue | accept_churn/burst/100 | ops_per_sec | 431.9 ops/s | 443.3 ops/s | 🟢▲ +3.36% | 0.81% |
| macos | kqueue | accept_churn/concurrent/1 | ops_per_sec | 19.58K ops/s | 20.18K ops/s | 🟢▲ +3.49% | 1.03% |
linux — full results (226 benchmarks, 5 iterations, 1.5s each)
accept_churn
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| burst/10 | epoll | ops_per_sec | 1.88K ops/s | 1.91K ops/s | 🟢▲ +2.01% | 1.01% |
| burst/10 | uring | ops_per_sec | 1.71K ops/s | 1.73K ops/s | 🟢▲ +1.32% | 0.88% |
| burst/100 | epoll | ops_per_sec | 189.3 ops/s | 192.6 ops/s | 🟢▲ +2.10% | 1.11% |
| burst/100 | uring | ops_per_sec | 174.3 ops/s | 177.2 ops/s | 🟢▲ +1.89% | 0.57% |
| burst_lockless/10 | epoll | ops_per_sec | 1.90K ops/s | 1.93K ops/s | 🟢▲ +2.09% | 1.17% |
| burst_lockless/10 | uring | ops_per_sec | 1.83K ops/s | 1.85K ops/s | 🟢▲ +1.54% | 0.99% |
| burst_lockless/100 | epoll | ops_per_sec | 191.0 ops/s | 194.1 ops/s | 🟢▲ +2.06% | 1.07% |
| burst_lockless/100 | uring | ops_per_sec | 186.3 ops/s | 189.6 ops/s | 🟢▲ +2.22% | 0.99% |
| concurrent/1 | epoll | ops_per_sec | 14.98K ops/s | 15.29K ops/s | 🟢▲ +2.41% | 0.94% |
| concurrent/1 | uring | ops_per_sec | 12.77K ops/s | 12.99K ops/s | 🟢▲ +1.76% | 0.80% |
| concurrent/16 | epoll | ops_per_sec | 14.99K ops/s | 15.31K ops/s | 🟢▲ +2.53% | 1.13% |
| concurrent/16 | uring | ops_per_sec | 12.64K ops/s | 12.85K ops/s | 🟢▲ +1.69% | 0.85% |
| concurrent/4 | epoll | ops_per_sec | 14.98K ops/s | 15.29K ops/s | 🟢▲ +2.30% | 0.95% |
| concurrent/4 | uring | ops_per_sec | 12.75K ops/s | 12.91K ops/s | 🟢▲ +1.07% | 1.11% |
| sequential | epoll | ops_per_sec | 14.99K ops/s | 15.31K ops/s | 🟢▲ +2.46% | 1.26% |
| sequential | uring | ops_per_sec | 12.77K ops/s | 12.98K ops/s | 🟢▲ +1.54% | 1.14% |
| sequential_lockless | epoll | ops_per_sec | 15.05K ops/s | 15.36K ops/s | 🟢▲ +2.27% | 1.13% |
| sequential_lockless | uring | ops_per_sec | 13.66K ops/s | 13.90K ops/s | 🟢▲ +1.86% | 0.98% |
fan_out
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent_parents/1 | epoll | ops_per_sec | 3.71K ops/s | 3.69K ops/s | 🟢▲ +0.03% | 1.13% |
| concurrent_parents/1 | uring | ops_per_sec | 3.45K ops/s | 3.44K ops/s | 🟢▲ +0.09% | 1.20% |
| concurrent_parents/16 | epoll | ops_per_sec | 3.58K ops/s | 3.58K ops/s | 🔴▼ -0.20% | 0.49% |
| concurrent_parents/16 | uring | ops_per_sec | 3.33K ops/s | 3.31K ops/s | 🔴▼ -0.23% | 1.04% |
| concurrent_parents/4 | epoll | ops_per_sec | 3.61K ops/s | 3.59K ops/s | 🔴▼ -0.39% | 1.11% |
| concurrent_parents/4 | uring | ops_per_sec | 3.36K ops/s | 3.34K ops/s | 🔴▼ -0.06% | 1.13% |
| concurrent_parents_lockless/1 | epoll | ops_per_sec | 3.73K ops/s | 3.73K ops/s | 🟢▲ +0.06% | 0.20% |
| concurrent_parents_lockless/1 | uring | ops_per_sec | 3.67K ops/s | 3.66K ops/s | 🔴▼ -0.15% | 0.82% |
| concurrent_parents_lockless/16 | epoll | ops_per_sec | 3.61K ops/s | 3.61K ops/s | 🔴▼ -0.18% | 0.18% |
| concurrent_parents_lockless/16 | uring | ops_per_sec | 3.52K ops/s | 3.52K ops/s | 🔴▼ -0.28% | 0.38% |
| concurrent_parents_lockless/4 | epoll | ops_per_sec | 3.63K ops/s | 3.63K ops/s | 🔴▼ -0.03% | 0.15% |
| concurrent_parents_lockless/4 | uring | ops_per_sec | 3.55K ops/s | 3.55K ops/s | 🔴▼ -0.03% | 0.49% |
| fork_join/1 | epoll | ops_per_sec | 54.94K ops/s | 54.75K ops/s | 🟢▲ +0.09% | 1.04% |
| fork_join/1 | uring | ops_per_sec | 53.48K ops/s | 53.30K ops/s | 🟢▲ +0.01% | 1.05% |
| fork_join/16 | epoll | ops_per_sec | 3.69K ops/s | 3.70K ops/s | 🟢▲ +0.46% | 0.26% |
| fork_join/16 | uring | ops_per_sec | 3.45K ops/s | 3.45K ops/s | 🔴▼ -0.25% | 1.01% |
| fork_join/4 | epoll | ops_per_sec | 14.64K ops/s | 14.65K ops/s | 🟢▲ +0.01% | 0.25% |
| fork_join/4 | uring | ops_per_sec | 13.79K ops/s | 13.71K ops/s | 🔴▼ -0.27% | 1.30% |
| fork_join/64 | epoll | ops_per_sec | 897.4 ops/s | 900.8 ops/s | 🟢▲ +0.24% | 0.19% |
| fork_join/64 | uring | ops_per_sec | 813.7 ops/s | 817.0 ops/s | 🟢▲ +0.02% | 1.16% |
| fork_join_lockless/1 | epoll | ops_per_sec | 55.59K ops/s | 55.51K ops/s | 🔴▼ -0.22% | 0.18% |
| fork_join_lockless/1 | uring | ops_per_sec | 55.95K ops/s | 56.13K ops/s | 🔴▼ -0.08% | 1.11% |
| fork_join_lockless/16 | epoll | ops_per_sec | 3.73K ops/s | 3.73K ops/s | 🟢▲ +0.06% | 0.20% |
| fork_join_lockless/16 | uring | ops_per_sec | 3.67K ops/s | 3.67K ops/s | 🟢▲ +0.40% | 1.03% |
| fork_join_lockless/4 | epoll | ops_per_sec | 14.80K ops/s | 14.82K ops/s | 🟢▲ +0.06% | 0.25% |
| fork_join_lockless/4 | uring | ops_per_sec | 14.61K ops/s | 14.58K ops/s | 🔴▼ -0.18% | 1.23% |
| fork_join_lockless/64 | epoll | ops_per_sec | 907.8 ops/s | 909.3 ops/s | 🟢▲ +0.31% | 0.26% |
| fork_join_lockless/64 | uring | ops_per_sec | 870.1 ops/s | 869.5 ops/s | 🟢▲ +0.30% | 1.05% |
| nested/16 | epoll | ops_per_sec | 895.2 ops/s | 892.7 ops/s | 🟢▲ +0.25% | 1.12% |
| nested/16 | uring | ops_per_sec | 810.3 ops/s | 802.2 ops/s | 🔴▼ -0.49% | 1.06% |
| nested/4 | epoll | ops_per_sec | 3.68K ops/s | 3.67K ops/s | 🟢▲ +0.04% | 1.25% |
| nested/4 | uring | ops_per_sec | 3.42K ops/s | 3.41K ops/s | 🔴▼ -0.12% | 1.19% |
| nested_lockless/16 | epoll | ops_per_sec | 905.0 ops/s | 902.7 ops/s | 🟢▲ +0.05% | 1.01% |
| nested_lockless/16 | uring | ops_per_sec | 861.0 ops/s | 856.9 ops/s | 🔴▼ -0.27% | 0.95% |
| nested_lockless/4 | epoll | ops_per_sec | 3.72K ops/s | 3.71K ops/s | 🟢▲ +0.11% | 1.15% |
| nested_lockless/4 | uring | ops_per_sec | 3.65K ops/s | 3.63K ops/s | 🔴▼ -0.49% | 1.13% |
http_server
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | epoll | ops_per_sec | 55.12K ops/s | 55.36K ops/s | 🟢▲ +0.29% | 0.94% |
| concurrent/1 | uring | ops_per_sec | 53.47K ops/s | 53.84K ops/s | 🟢▲ +0.27% | 0.86% |
| concurrent/16 | epoll | ops_per_sec | 57.82K ops/s | 57.84K ops/s | 🟢▲ +0.04% | 0.15% |
| concurrent/16 | uring | ops_per_sec | 52.82K ops/s | 53.20K ops/s | 🟢▲ +0.14% | 1.08% |
| concurrent/32 | epoll | ops_per_sec | 57.40K ops/s | 57.46K ops/s | 🟢▲ +0.19% | 0.29% |
| concurrent/32 | uring | ops_per_sec | 52.44K ops/s | 52.82K ops/s | 🟢▲ +0.26% | 1.13% |
| concurrent/4 | epoll | ops_per_sec | 57.16K ops/s | 57.45K ops/s | 🟢▲ +0.36% | 0.96% |
| concurrent/4 | uring | ops_per_sec | 52.82K ops/s | 53.34K ops/s | 🟢▲ +0.40% | 1.21% |
| multithread/1 | epoll | ops_per_sec | 57.38K ops/s | 57.45K ops/s | 🟢▲ +0.08% | 0.11% |
| multithread/1 | uring | ops_per_sec | 52.43K ops/s | 52.82K ops/s | 🟢▲ +0.26% | 1.13% |
| multithread/16 | epoll | ops_per_sec | 162.1K ops/s | 162.3K ops/s | 🔴▼ -0.09% | 0.41% |
| multithread/16 | uring | ops_per_sec | 75.25K ops/s | 75.47K ops/s | 🟢▲ +0.42% | 19.53% |
| multithread/2 | epoll | ops_per_sec | 87.31K ops/s | 86.90K ops/s | 🔴▼ -0.73% | 0.84% |
| multithread/2 | uring | ops_per_sec | 90.43K ops/s | 91.36K ops/s | 🟢▲ +0.86% | 0.62% |
| multithread/4 | epoll | ops_per_sec | 159.8K ops/s | 159.7K ops/s | 🔴▼ -0.26% | 0.73% |
| multithread/4 | uring | ops_per_sec | 80.15K ops/s | 80.32K ops/s | 🟢▲ +0.31% | 0.27% |
| multithread/8 | epoll | ops_per_sec | 162.2K ops/s | 161.9K ops/s | 🔴▼ -0.29% | 0.31% |
| multithread/8 | uring | ops_per_sec | 77.50K ops/s | 77.83K ops/s | 🟢▲ +0.33% | 0.26% |
| single_conn | epoll | ops_per_sec | 55.09K ops/s | 55.30K ops/s | 🟢▲ +0.06% | 0.79% |
| single_conn | uring | ops_per_sec | 53.34K ops/s | 53.52K ops/s | 🟢▲ +0.45% | 0.39% |
| single_conn_lockless | epoll | ops_per_sec | 55.74K ops/s | 56.11K ops/s | 🟢▲ +0.61% | 0.99% |
| single_conn_lockless | uring | ops_per_sec | 55.95K ops/s | 56.27K ops/s | 🟢▲ +0.53% | 0.33% |
local_socket_latency
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | epoll | latency_mean_ns | 7.17 µs | 7.23 µs | 🟢▲ +0.47% | 4.08% |
| concurrent/1 | uring | latency_mean_ns | 6.56 µs | 6.56 µs | 🔴▼ -0.26% | 1.16% |
| concurrent/16 | epoll | latency_mean_ns | 109.89 µs | 109.72 µs | 🟢▲ +0.34% | 0.91% |
| concurrent/16 | uring | latency_mean_ns | 108.11 µs | 108.02 µs | 🟢▲ +0.19% | 1.27% |
| concurrent/4 | epoll | latency_mean_ns | 27.74 µs | 27.70 µs | 🟢▲ +0.16% | 1.42% |
| concurrent/4 | uring | latency_mean_ns | 27.03 µs | 26.67 µs | 🟢▲ +2.13% | 2.28% |
| concurrent_lockless/1 | epoll | latency_mean_ns | 7.25 µs | 7.25 µs | 🟢▲ +0.31% | 5.73% |
| concurrent_lockless/1 | uring | latency_mean_ns | 6.55 µs | 6.81 µs | 🔴▼ -0.03% | 6.08% |
| concurrent_lockless/16 | epoll | latency_mean_ns | 108.34 µs | 108.63 µs | 🔴▼ -0.07% | 0.91% |
| concurrent_lockless/16 | uring | latency_mean_ns | 108.02 µs | 107.74 µs | 🟢▲ +0.28% | 0.70% |
| concurrent_lockless/4 | epoll | latency_mean_ns | 27.19 µs | 27.48 µs | 🟢▲ +0.09% | 2.12% |
| concurrent_lockless/4 | uring | latency_mean_ns | 26.86 µs | 26.68 µs | 🟢▲ +0.30% | 1.23% |
| pingpong/1 | epoll | latency_mean_ns | 7.20 µs | 7.18 µs | 🟢▲ +0.52% | 4.28% |
| pingpong/1 | uring | latency_mean_ns | 6.60 µs | 6.61 µs | 🟢▲ +0.25% | 2.82% |
| pingpong/1024 | epoll | latency_mean_ns | 8.02 µs | 7.59 µs | 🟢▲ +8.21% | 4.93% |
| pingpong/1024 | uring | latency_mean_ns | 7.09 µs | 7.22 µs | 🟢▲ +0.22% | 5.18% |
| pingpong/64 | epoll | latency_mean_ns | 7.38 µs | 7.08 µs | 🟢▲ +0.72% | 4.80% |
| pingpong/64 | uring | latency_mean_ns | 6.72 µs | 6.57 µs | 🟢▲ +0.54% | 4.35% |
| pingpong_lockless/1 | epoll | latency_mean_ns | 6.96 µs | 6.97 µs | 🔴▼ -0.04% | 0.40% |
| pingpong_lockless/1 | uring | latency_mean_ns | 6.54 µs | 6.53 µs | 🟢▲ +0.44% | 0.67% |
| pingpong_lockless/1024 | epoll | latency_mean_ns | 7.52 µs | 7.52 µs | ⚪ 0.00% | 5.09% |
| pingpong_lockless/1024 | uring | latency_mean_ns | 7.26 µs | 7.30 µs | 🟢▲ +0.17% | 4.53% |
| pingpong_lockless/64 | epoll | latency_mean_ns | 7.14 µs | 7.28 µs | 🔴▼ -0.02% | 5.21% |
| pingpong_lockless/64 | uring | latency_mean_ns | 6.57 µs | 6.70 µs | 🔴▼ -0.22% | 4.31% |
local_socket_throughput
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| bidirectional/1024 | epoll | bytes_per_sec | 305.3 MB/s | 304.9 MB/s | 🔴▼ -0.13% | 1.04% |
| bidirectional/1024 | uring | bytes_per_sec | 301.9 MB/s | 301.7 MB/s | ⚪ 0.00% | 0.65% |
| bidirectional/1048576 | epoll | bytes_per_sec | 3.16 GB/s | 3.16 GB/s | 🟢▲ +0.29% | 2.32% |
| bidirectional/1048576 | uring | bytes_per_sec | 3.32 GB/s | 3.33 GB/s | 🔴▼ -0.35% | 1.76% |
| bidirectional/16384 | epoll | bytes_per_sec | 3.11 GB/s | 3.02 GB/s | 🔴▼ -3.23% | 1.74% |
| bidirectional/16384 | uring | bytes_per_sec | 2.39 GB/s | 2.40 GB/s | 🔴▼ -0.37% | 2.48% |
| bidirectional/262144 | epoll | bytes_per_sec | 3.18 GB/s | 3.20 GB/s | 🟢▲ +0.83% | 2.53% |
| bidirectional/262144 | uring | bytes_per_sec | 3.31 GB/s | 3.31 GB/s | 🟢▲ +0.34% | 1.24% |
| bidirectional/4096 | epoll | bytes_per_sec | 1.01 GB/s | 998.8 MB/s | 🔴▼ -0.64% | 0.78% |
| bidirectional/4096 | uring | bytes_per_sec | 995.1 MB/s | 989.4 MB/s | 🔴▼ -0.53% | 0.72% |
| bidirectional/65536 | epoll | bytes_per_sec | 2.98 GB/s | 2.97 GB/s | 🔴▼ -1.53% | 1.88% |
| bidirectional/65536 | uring | bytes_per_sec | 3.05 GB/s | 3.01 GB/s | 🔴▼ -0.76% | 2.40% |
| bidirectional_lockless/1024 | epoll | bytes_per_sec | 308.1 MB/s | 308.7 MB/s | 🔴▼ -0.33% | 1.24% |
| bidirectional_lockless/1024 | uring | bytes_per_sec | 304.7 MB/s | 304.8 MB/s | 🟢▲ +0.90% | 0.81% |
| bidirectional_lockless/1048576 | epoll | bytes_per_sec | 3.16 GB/s | 3.17 GB/s | 🔴▼ -0.78% | 2.63% |
| bidirectional_lockless/1048576 | uring | bytes_per_sec | 3.39 GB/s | 3.40 GB/s | 🔴▼ -0.97% | 2.45% |
| bidirectional_lockless/16384 | epoll | bytes_per_sec | 3.08 GB/s | 3.09 GB/s | 🔴▼ -0.04% | 2.45% |
| bidirectional_lockless/16384 | uring | bytes_per_sec | 2.59 GB/s | 2.62 GB/s | 🟢▲ +1.44% | 2.94% |
| bidirectional_lockless/262144 | epoll | bytes_per_sec | 3.19 GB/s | 3.20 GB/s | 🟢▲ +0.56% | 2.88% |
| bidirectional_lockless/262144 | uring | bytes_per_sec | 3.37 GB/s | 3.37 GB/s | 🟢▲ +1.13% | 1.44% |
| bidirectional_lockless/4096 | epoll | bytes_per_sec | 1.02 GB/s | 1.01 GB/s | 🔴▼ -0.51% | 0.84% |
| bidirectional_lockless/4096 | uring | bytes_per_sec | 1.00 GB/s | 991.0 MB/s | 🔴▼ -0.79% | 1.21% |
| bidirectional_lockless/65536 | epoll | bytes_per_sec | 2.98 GB/s | 2.95 GB/s | 🔴▼ -1.69% | 2.02% |
| bidirectional_lockless/65536 | uring | bytes_per_sec | 3.22 GB/s | 3.18 GB/s | 🔴▼ -0.88% | 2.28% |
| unidirectional/1024 | epoll | bytes_per_sec | 297.5 MB/s | 297.1 MB/s | 🔴▼ -0.47% | 1.07% |
| unidirectional/1024 | uring | bytes_per_sec | 303.1 MB/s | 302.2 MB/s | 🟢▲ +0.10% | 1.01% |
| unidirectional/1048576 | epoll | bytes_per_sec | 3.30 GB/s | 3.29 GB/s | 🔴▼ -1.02% | 2.24% |
| unidirectional/1048576 | uring | bytes_per_sec | 3.46 GB/s | 3.46 GB/s | 🔴▼ -1.35% | 2.40% |
| unidirectional/16384 | epoll | bytes_per_sec | 3.04 GB/s | 3.05 GB/s | 🟢▲ +0.41% | 1.90% |
| unidirectional/16384 | uring | bytes_per_sec | 2.63 GB/s | 2.59 GB/s | 🔴▼ -1.50% | 3.36% |
| unidirectional/262144 | epoll | bytes_per_sec | 3.29 GB/s | 3.33 GB/s | 🟢▲ +0.26% | 2.45% |
| unidirectional/262144 | uring | bytes_per_sec | 3.42 GB/s | 3.45 GB/s | 🟢▲ +1.48% | 2.90% |
| unidirectional/4096 | epoll | bytes_per_sec | 989.3 MB/s | 979.6 MB/s | 🔴▼ -0.94% | 0.55% |
| unidirectional/4096 | uring | bytes_per_sec | 991.0 MB/s | 992.2 MB/s | 🟢▲ +0.74% | 1.87% |
| unidirectional/65536 | epoll | bytes_per_sec | 3.27 GB/s | 3.25 GB/s | 🔴▼ -0.79% | 1.47% |
| unidirectional/65536 | uring | bytes_per_sec | 3.31 GB/s | 3.32 GB/s | 🟢▲ +0.80% | 2.65% |
| unidirectional_lockless/1024 | epoll | bytes_per_sec | 301.9 MB/s | 301.6 MB/s | 🟢▲ +0.26% | 1.16% |
| unidirectional_lockless/1024 | uring | bytes_per_sec | 305.1 MB/s | 304.5 MB/s | 🔴▼ -0.17% | 0.95% |
| unidirectional_lockless/1048576 | epoll | bytes_per_sec | 3.31 GB/s | 3.32 GB/s | 🟢▲ +0.61% | 3.14% |
| unidirectional_lockless/1048576 | uring | bytes_per_sec | 3.39 GB/s | 3.40 GB/s | 🟢▲ +0.39% | 2.23% |
| unidirectional_lockless/16384 | epoll | bytes_per_sec | 3.07 GB/s | 3.08 GB/s | 🟢▲ +1.00% | 1.74% |
| unidirectional_lockless/16384 | uring | bytes_per_sec | 2.67 GB/s | 2.60 GB/s | 🔴▼ -3.03% | 3.46% |
| unidirectional_lockless/262144 | epoll | bytes_per_sec | 3.30 GB/s | 3.35 GB/s | 🟢▲ +0.72% | 1.68% |
| unidirectional_lockless/262144 | uring | bytes_per_sec | 3.38 GB/s | 3.39 GB/s | 🟢▲ +2.44% | 4.16% |
| unidirectional_lockless/4096 | epoll | bytes_per_sec | 996.7 MB/s | 989.6 MB/s | 🔴▼ -1.16% | 0.97% |
| unidirectional_lockless/4096 | uring | bytes_per_sec | 991.4 MB/s | 995.2 MB/s | 🔴▼ -0.54% | 1.15% |
| unidirectional_lockless/65536 | epoll | bytes_per_sec | 3.25 GB/s | 3.26 GB/s | 🟢▲ +0.40% | 1.15% |
| unidirectional_lockless/65536 | uring | bytes_per_sec | 3.31 GB/s | 3.30 GB/s | 🔴▼ -0.31% | 2.04% |
socket_latency
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | epoll | latency_mean_ns | 14.79 µs | 14.71 µs | 🟢▲ +0.28% | 1.06% |
| concurrent/1 | uring | latency_mean_ns | 14.53 µs | 14.55 µs | 🔴▼ -0.15% | 0.39% |
| concurrent/16 | epoll | latency_mean_ns | 233.21 µs | 233.11 µs | 🟢▲ +0.12% | 0.16% |
| concurrent/16 | uring | latency_mean_ns | 235.46 µs | 235.34 µs | 🟢▲ +0.01% | 0.33% |
| concurrent/4 | epoll | latency_mean_ns | 58.23 µs | 58.20 µs | 🔴▼ -0.05% | 0.18% |
| concurrent/4 | uring | latency_mean_ns | 58.40 µs | 58.41 µs | 🔴▼ -0.03% | 0.37% |
| concurrent_lockless/1 | epoll | latency_mean_ns | 14.67 µs | 14.62 µs | 🟢▲ +0.29% | 0.86% |
| concurrent_lockless/1 | uring | latency_mean_ns | 14.54 µs | 14.52 µs | 🟢▲ +0.24% | 0.49% |
| concurrent_lockless/16 | epoll | latency_mean_ns | 231.96 µs | 230.50 µs | 🟢▲ +0.15% | 1.08% |
| concurrent_lockless/16 | uring | latency_mean_ns | 235.27 µs | 234.75 µs | 🟢▲ +0.31% | 0.32% |
| concurrent_lockless/4 | epoll | latency_mean_ns | 57.88 µs | 57.52 µs | 🟢▲ +0.15% | 1.21% |
| concurrent_lockless/4 | uring | latency_mean_ns | 58.41 µs | 58.36 µs | 🟢▲ +0.27% | 0.32% |
| pingpong/1 | epoll | latency_mean_ns | 14.63 µs | 14.60 µs | 🟢▲ +0.14% | 1.15% |
| pingpong/1 | uring | latency_mean_ns | 14.46 µs | 14.50 µs | 🔴▼ -0.39% | 0.27% |
| pingpong/1024 | epoll | latency_mean_ns | 15.03 µs | 14.92 µs | 🟢▲ +0.22% | 1.07% |
| pingpong/1024 | uring | latency_mean_ns | 14.81 µs | 14.79 µs | 🟢▲ +0.24% | 0.35% |
| pingpong/64 | epoll | latency_mean_ns | 14.73 µs | 14.64 µs | 🟢▲ +0.04% | 1.33% |
| pingpong/64 | uring | latency_mean_ns | 14.54 µs | 14.55 µs | 🟢▲ +0.04% | 0.32% |
| pingpong_lockless/1 | epoll | latency_mean_ns | 14.61 µs | 14.54 µs | 🔴▼ -0.03% | 1.12% |
| pingpong_lockless/1 | uring | latency_mean_ns | 14.45 µs | 14.45 µs | 🟢▲ +0.02% | 0.35% |
| pingpong_lockless/1024 | epoll | latency_mean_ns | 14.93 µs | 14.87 µs | 🟢▲ +0.13% | 1.15% |
| pingpong_lockless/1024 | uring | latency_mean_ns | 14.76 µs | 14.76 µs | 🟢▲ +0.13% | 0.46% |
| pingpong_lockless/64 | epoll | latency_mean_ns | 14.67 µs | 14.61 µs | 🟢▲ +0.08% | 1.16% |
| pingpong_lockless/64 | uring | latency_mean_ns | 14.53 µs | 14.53 µs | 🔴▼ -0.09% | 0.40% |
socket_throughput
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| bidirectional/1024 | epoll | bytes_per_sec | 135.4 MB/s | 134.2 MB/s | 🔴▼ -0.32% | 1.34% |
| bidirectional/1024 | uring | bytes_per_sec | 140.9 MB/s | 140.5 MB/s | 🔴▼ -0.18% | 0.99% |
| bidirectional/1048576 | epoll | bytes_per_sec | 3.30 GB/s | 3.32 GB/s | 🟢▲ +0.15% | 2.10% |
| bidirectional/1048576 | uring | bytes_per_sec | 3.24 GB/s | 3.26 GB/s | 🟢▲ +0.42% | 0.63% |
| bidirectional/16384 | epoll | bytes_per_sec | 1.64 GB/s | 1.65 GB/s | 🟢▲ +0.65% | 0.87% |
| bidirectional/16384 | uring | bytes_per_sec | 1.55 GB/s | 1.54 GB/s | 🟢▲ +0.39% | 2.50% |
| bidirectional/262144 | epoll | bytes_per_sec | 3.23 GB/s | 3.21 GB/s | 🔴▼ -0.24% | 1.05% |
| bidirectional/262144 | uring | bytes_per_sec | 3.21 GB/s | 3.15 GB/s | 🔴▼ -1.77% | 1.19% |
| bidirectional/4096 | epoll | bytes_per_sec | 507.3 MB/s | 506.8 MB/s | 🟢▲ +0.42% | 1.35% |
| bidirectional/4096 | uring | bytes_per_sec | 492.0 MB/s | 491.2 MB/s | 🟢▲ +0.28% | 1.45% |
| bidirectional/65536 | epoll | bytes_per_sec | 2.64 GB/s | 2.58 GB/s | 🔴▼ -2.02% | 2.32% |
| bidirectional/65536 | uring | bytes_per_sec | 2.78 GB/s | 2.80 GB/s | 🟢▲ +0.55% | 1.02% |
| bidirectional_lockless/1024 | epoll | bytes_per_sec | 135.2 MB/s | 134.6 MB/s | 🔴▼ -0.36% | 0.99% |
| bidirectional_lockless/1024 | uring | bytes_per_sec | 140.8 MB/s | 140.9 MB/s | 🟢▲ +0.05% | 0.41% |
| bidirectional_lockless/1048576 | epoll | bytes_per_sec | 3.30 GB/s | 3.34 GB/s | 🟢▲ +0.20% | 3.26% |
| bidirectional_lockless/1048576 | uring | bytes_per_sec | 3.36 GB/s | 3.32 GB/s | 🔴▼ -0.98% | 0.91% |
| bidirectional_lockless/16384 | epoll | bytes_per_sec | 1.64 GB/s | 1.63 GB/s | 🟢▲ +0.09% | 2.23% |
| bidirectional_lockless/16384 | uring | bytes_per_sec | 1.54 GB/s | 1.54 GB/s | 🟢▲ +0.09% | 0.39% |
| bidirectional_lockless/262144 | epoll | bytes_per_sec | 3.22 GB/s | 3.22 GB/s | 🟢▲ +0.22% | 0.99% |
| bidirectional_lockless/262144 | uring | bytes_per_sec | 3.28 GB/s | 3.24 GB/s | 🔴▼ -1.09% | 1.00% |
| bidirectional_lockless/4096 | epoll | bytes_per_sec | 509.4 MB/s | 506.9 MB/s | 🔴▼ -0.73% | 0.72% |
| bidirectional_lockless/4096 | uring | bytes_per_sec | 493.8 MB/s | 494.2 MB/s | 🟢▲ +0.17% | 0.43% |
| bidirectional_lockless/65536 | epoll | bytes_per_sec | 2.58 GB/s | 2.58 GB/s | 🟢▲ +2.64% | 3.33% |
| bidirectional_lockless/65536 | uring | bytes_per_sec | 2.76 GB/s | 2.78 GB/s | 🟢▲ +1.38% | 1.69% |
| multithread/2 | epoll | bytes_per_sec | 3.41 GB/s | 3.39 GB/s | 🔴▼ -0.40% | 0.50% |
| multithread/2 | uring | bytes_per_sec | 3.63 GB/s | 3.67 GB/s | 🔴▼ -0.17% | 1.15% |
| multithread/4 | epoll | bytes_per_sec | 4.85 GB/s | 4.88 GB/s | 🟢▲ +0.35% | 0.51% |
| multithread/4 | uring | bytes_per_sec | 5.07 GB/s | 5.06 GB/s | 🔴▼ -0.48% | 0.45% |
| multithread/8 | epoll | bytes_per_sec | 4.96 GB/s | 4.97 GB/s | 🟢▲ +0.19% | 0.14% |
| multithread/8 | uring | bytes_per_sec | 5.13 GB/s | 5.14 GB/s | 🟢▲ +0.07% | 0.23% |
| unidirectional/1024 | epoll | bytes_per_sec | 125.5 MB/s | 125.6 MB/s | ⚪ 0.00% | 0.25% |
| unidirectional/1024 | uring | bytes_per_sec | 139.5 MB/s | 140.3 MB/s | 🟢▲ +0.37% | 1.21% |
| unidirectional/1048576 | epoll | bytes_per_sec | 3.34 GB/s | 3.36 GB/s | 🟢▲ +0.29% | 1.45% |
| unidirectional/1048576 | uring | bytes_per_sec | 3.41 GB/s | 3.43 GB/s | 🟢▲ +0.33% | 0.82% |
| unidirectional/16384 | epoll | bytes_per_sec | 1.56 GB/s | 1.54 GB/s | 🔴▼ -1.20% | 1.35% |
| unidirectional/16384 | uring | bytes_per_sec | 1.55 GB/s | 1.58 GB/s | 🟢▲ +1.83% | 2.10% |
| unidirectional/262144 | epoll | bytes_per_sec | 3.34 GB/s | 3.33 GB/s | 🔴▼ -0.82% | 0.71% |
| unidirectional/262144 | uring | bytes_per_sec | 3.20 GB/s | 3.21 GB/s | 🔴▼ -0.20% | 0.77% |
| unidirectional/4096 | epoll | bytes_per_sec | 470.5 MB/s | 472.1 MB/s | 🟢▲ +0.14% | 0.64% |
| unidirectional/4096 | uring | bytes_per_sec | 489.5 MB/s | 492.0 MB/s | 🟢▲ +0.06% | 1.03% |
| unidirectional/65536 | epoll | bytes_per_sec | 2.63 GB/s | 2.69 GB/s | 🟢▲ +0.13% | 5.37% |
| unidirectional/65536 | uring | bytes_per_sec | 2.71 GB/s | 2.70 GB/s | 🟢▲ +0.89% | 2.93% |
| unidirectional_lockless/1024 | epoll | bytes_per_sec | 126.6 MB/s | 126.3 MB/s | 🔴▼ -0.02% | 0.71% |
| unidirectional_lockless/1024 | uring | bytes_per_sec | 139.4 MB/s | 139.1 MB/s | 🔴▼ -0.24% | 0.48% |
| unidirectional_lockless/1048576 | epoll | bytes_per_sec | 3.39 GB/s | 3.37 GB/s | 🔴▼ -0.57% | 1.67% |
| unidirectional_lockless/1048576 | uring | bytes_per_sec | 3.36 GB/s | 3.38 GB/s | 🟢▲ +0.32% | 0.98% |
| unidirectional_lockless/16384 | epoll | bytes_per_sec | 1.58 GB/s | 1.57 GB/s | 🔴▼ -1.38% | 1.44% |
| unidirectional_lockless/16384 | uring | bytes_per_sec | 1.61 GB/s | 1.63 GB/s | 🟢▲ +0.89% | 1.35% |
| unidirectional_lockless/262144 | epoll | bytes_per_sec | 3.38 GB/s | 3.35 GB/s | 🔴▼ -0.40% | 1.82% |
| unidirectional_lockless/262144 | uring | bytes_per_sec | 3.26 GB/s | 3.25 GB/s | 🟢▲ +0.17% | 1.20% |
| unidirectional_lockless/4096 | epoll | bytes_per_sec | 475.8 MB/s | 474.7 MB/s | 🟢▲ +0.13% | 1.14% |
| unidirectional_lockless/4096 | uring | bytes_per_sec | 492.9 MB/s | 492.0 MB/s | 🟢▲ +0.44% | 0.94% |
| unidirectional_lockless/65536 | epoll | bytes_per_sec | 2.76 GB/s | 2.75 GB/s | 🔴▼ -0.22% | 2.75% |
| unidirectional_lockless/65536 | uring | bytes_per_sec | 2.75 GB/s | 2.71 GB/s | 🔴▼ -0.12% | 3.79% |
windows — full results (77 benchmarks, 5 iterations, 1.5s each)
accept_churn
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| burst/10 | iocp | ops_per_sec | 1.53K ops/s | 1.55K ops/s | 🟢▲ +1.42% | 0.25% |
| burst/100 | iocp | ops_per_sec | 149.1 ops/s | 155.6 ops/s | 🟢▲ +4.40% | 0.93% |
| burst_lockless/10 | iocp | ops_per_sec | 1.53K ops/s | 1.56K ops/s | 🟢▲ +1.65% | 0.18% |
| burst_lockless/100 | iocp | ops_per_sec | 152.4 ops/s | 158.5 ops/s | 🟢▲ +3.85% | 0.64% |
| concurrent/1 | iocp | ops_per_sec | 12.24K ops/s | 12.49K ops/s | 🟢▲ +1.84% | 1.42% |
| concurrent/16 | iocp | ops_per_sec | 13.21K ops/s | 13.46K ops/s | 🟢▲ +1.79% | 0.45% |
| concurrent/4 | iocp | ops_per_sec | 12.92K ops/s | 13.15K ops/s | 🟢▲ +1.88% | 0.38% |
| sequential | iocp | ops_per_sec | 12.19K ops/s | 12.44K ops/s | 🟢▲ +1.62% | 1.26% |
| sequential_lockless | iocp | ops_per_sec | 12.28K ops/s | 12.51K ops/s | 🟢▲ +1.14% | 1.33% |
fan_out
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent_parents/1 | iocp | ops_per_sec | 7.20K ops/s | 7.23K ops/s | 🟢▲ +0.23% | 0.36% |
| concurrent_parents/16 | iocp | ops_per_sec | 6.46K ops/s | 6.47K ops/s | 🟢▲ +0.05% | 1.41% |
| concurrent_parents/4 | iocp | ops_per_sec | 6.91K ops/s | 6.95K ops/s | 🟢▲ +0.83% | 0.79% |
| concurrent_parents_lockless/1 | iocp | ops_per_sec | 7.20K ops/s | 7.22K ops/s | 🟢▲ +0.50% | 0.39% |
| concurrent_parents_lockless/16 | iocp | ops_per_sec | 6.49K ops/s | 6.51K ops/s | 🟢▲ +0.32% | 1.50% |
| concurrent_parents_lockless/4 | iocp | ops_per_sec | 6.93K ops/s | 6.98K ops/s | 🟢▲ +0.75% | 0.64% |
| fork_join/1 | iocp | ops_per_sec | 113.5K ops/s | 113.6K ops/s | 🟢▲ +0.35% | 0.46% |
| fork_join/16 | iocp | ops_per_sec | 7.17K ops/s | 7.24K ops/s | 🟢▲ +0.52% | 0.69% |
| fork_join/4 | iocp | ops_per_sec | 29.37K ops/s | 29.41K ops/s | 🟢▲ +0.30% | 0.50% |
| fork_join/64 | iocp | ops_per_sec | 1.72K ops/s | 1.74K ops/s | 🟢▲ +0.47% | 1.25% |
| fork_join_lockless/1 | iocp | ops_per_sec | 113.3K ops/s | 113.6K ops/s | 🟢▲ +0.13% | 0.41% |
| fork_join_lockless/16 | iocp | ops_per_sec | 7.18K ops/s | 7.23K ops/s | 🟢▲ +0.30% | 0.31% |
| fork_join_lockless/4 | iocp | ops_per_sec | 29.31K ops/s | 29.42K ops/s | 🟢▲ +0.34% | 0.24% |
| fork_join_lockless/64 | iocp | ops_per_sec | 1.73K ops/s | 1.74K ops/s | 🟢▲ +0.67% | 1.00% |
| nested/16 | iocp | ops_per_sec | 1.70K ops/s | 1.71K ops/s | 🟢▲ +0.72% | 1.21% |
| nested/4 | iocp | ops_per_sec | 7.04K ops/s | 7.08K ops/s | 🟢▲ +0.60% | 0.25% |
| nested_lockless/16 | iocp | ops_per_sec | 1.70K ops/s | 1.71K ops/s | 🟢▲ +0.20% | 1.20% |
| nested_lockless/4 | iocp | ops_per_sec | 7.03K ops/s | 7.08K ops/s | 🟢▲ +0.74% | 0.32% |
http_server
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | iocp | ops_per_sec | 111.6K ops/s | 112.0K ops/s | 🟢▲ +0.58% | 0.49% |
| concurrent/16 | iocp | ops_per_sec | 108.3K ops/s | 109.2K ops/s | 🟢▲ +0.54% | 0.44% |
| concurrent/32 | iocp | ops_per_sec | 107.7K ops/s | 108.8K ops/s | 🟢▲ +1.12% | 0.31% |
| concurrent/4 | iocp | ops_per_sec | 109.2K ops/s | 109.7K ops/s | 🟢▲ +0.27% | 0.48% |
| multithread/1 | iocp | ops_per_sec | 107.8K ops/s | 108.9K ops/s | 🟢▲ +1.15% | 0.30% |
| multithread/16 | iocp | ops_per_sec | 266.1K ops/s | 267.1K ops/s | 🟢▲ +0.35% | 0.58% |
| multithread/2 | iocp | ops_per_sec | 180.9K ops/s | 182.3K ops/s | 🟢▲ +0.71% | 0.96% |
| multithread/4 | iocp | ops_per_sec | 224.6K ops/s | 225.7K ops/s | 🟢▲ +0.53% | 0.83% |
| multithread/8 | iocp | ops_per_sec | 265.5K ops/s | 267.7K ops/s | 🟢▲ +0.63% | 0.45% |
| single_conn | iocp | ops_per_sec | 111.8K ops/s | 111.8K ops/s | 🔴▼ -0.17% | 0.57% |
| single_conn_lockless | iocp | ops_per_sec | 111.7K ops/s | 112.2K ops/s | 🟢▲ +0.46% | 0.51% |
socket_latency
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | iocp | latency_mean_ns | 7.59 µs | 7.55 µs | 🟢▲ +0.36% | 0.33% |
| concurrent/16 | iocp | latency_mean_ns | 125.94 µs | 127.93 µs | 🔴▼ -1.01% | 3.55% |
| concurrent/4 | iocp | latency_mean_ns | 30.39 µs | 30.50 µs | 🔴▼ -0.34% | 0.52% |
| concurrent_lockless/1 | iocp | latency_mean_ns | 7.59 µs | 7.56 µs | 🟢▲ +0.17% | 0.39% |
| concurrent_lockless/16 | iocp | latency_mean_ns | 121.12 µs | 121.06 µs | 🟢▲ +0.14% | 0.38% |
| concurrent_lockless/4 | iocp | latency_mean_ns | 30.32 µs | 30.41 µs | 🔴▼ -0.42% | 0.35% |
| pingpong/1 | iocp | latency_mean_ns | 7.57 µs | 7.54 µs | 🟢▲ +0.38% | 0.44% |
| pingpong/1024 | iocp | latency_mean_ns | 7.68 µs | 7.69 µs | 🟢▲ +0.08% | 0.38% |
| pingpong/64 | iocp | latency_mean_ns | 7.59 µs | 7.58 µs | 🔴▼ -0.03% | 0.24% |
| pingpong_lockless/1 | iocp | latency_mean_ns | 7.56 µs | 7.53 µs | 🟢▲ +0.52% | 0.55% |
| pingpong_lockless/1024 | iocp | latency_mean_ns | 7.68 µs | 7.68 µs | 🟢▲ +0.05% | 0.26% |
| pingpong_lockless/64 | iocp | latency_mean_ns | 7.60 µs | 7.56 µs | 🟢▲ +0.61% | 0.26% |
socket_throughput
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| bidirectional/1024 | iocp | bytes_per_sec | 282.3 MB/s | 282.8 MB/s | 🟢▲ +0.07% | 0.64% |
| bidirectional/1048576 | iocp | bytes_per_sec | 5.72 GB/s | 5.20 GB/s | 🔴▼ -13.04% | 8.36% |
| bidirectional/16384 | iocp | bytes_per_sec | 3.75 GB/s | 3.77 GB/s | 🟢▲ +0.42% | 0.70% |
| bidirectional/262144 | iocp | bytes_per_sec | 9.41 GB/s | 9.62 GB/s | 🟢▲ +2.18% | 1.77% |
| bidirectional/4096 | iocp | bytes_per_sec | 1.08 GB/s | 1.09 GB/s | 🟢▲ +0.37% | 0.40% |
| bidirectional/65536 | iocp | bytes_per_sec | 9.01 GB/s | 9.09 GB/s | 🟢▲ +0.29% | 2.38% |
| bidirectional_lockless/1024 | iocp | bytes_per_sec | 281.9 MB/s | 282.5 MB/s | 🟢▲ +0.26% | 0.42% |
| bidirectional_lockless/1048576 | iocp | bytes_per_sec | 5.94 GB/s | 5.52 GB/s | 🔴▼ -8.07% | 6.07% |
| bidirectional_lockless/16384 | iocp | bytes_per_sec | 3.73 GB/s | 3.73 GB/s | 🔴▼ -0.05% | 0.67% |
| bidirectional_lockless/262144 | iocp | bytes_per_sec | 9.59 GB/s | 9.69 GB/s | 🟢▲ +1.84% | 2.56% |
| bidirectional_lockless/4096 | iocp | bytes_per_sec | 1.08 GB/s | 1.08 GB/s | 🟢▲ +0.31% | 0.39% |
| bidirectional_lockless/65536 | iocp | bytes_per_sec | 9.01 GB/s | 8.95 GB/s | 🔴▼ -0.59% | 1.70% |
| multithread/2 | iocp | bytes_per_sec | 12.80 GB/s | 12.72 GB/s | 🔴▼ -0.18% | 1.06% |
| multithread/4 | iocp | bytes_per_sec | 16.95 GB/s | 17.13 GB/s | 🟢▲ +0.27% | 1.17% |
| multithread/8 | iocp | bytes_per_sec | 18.42 GB/s | 18.50 GB/s | 🔴▼ -0.17% | 1.14% |
| unidirectional/1024 | iocp | bytes_per_sec | 285.4 MB/s | 286.5 MB/s | 🟢▲ +0.06% | 0.66% |
| unidirectional/1048576 | iocp | bytes_per_sec | 4.35 GB/s | 4.39 GB/s | 🟢▲ +1.73% | 5.29% |
| unidirectional/16384 | iocp | bytes_per_sec | 3.80 GB/s | 3.80 GB/s | 🔴▼ -0.16% | 0.41% |
| unidirectional/262144 | iocp | bytes_per_sec | 8.62 GB/s | 9.12 GB/s | 🟢▲ +5.37% | 5.29% |
| unidirectional/4096 | iocp | bytes_per_sec | 1.10 GB/s | 1.10 GB/s | 🔴▼ -0.23% | 0.57% |
| unidirectional/65536 | iocp | bytes_per_sec | 9.27 GB/s | 9.31 GB/s | 🟢▲ +0.04% | 1.73% |
| unidirectional_lockless/1024 | iocp | bytes_per_sec | 285.7 MB/s | 287.0 MB/s | 🟢▲ +0.54% | 0.44% |
| unidirectional_lockless/1048576 | iocp | bytes_per_sec | 5.19 GB/s | 4.85 GB/s | 🔴▼ -5.51% | 4.53% |
| unidirectional_lockless/16384 | iocp | bytes_per_sec | 3.79 GB/s | 3.81 GB/s | 🟢▲ +0.57% | 1.08% |
| unidirectional_lockless/262144 | iocp | bytes_per_sec | 9.66 GB/s | 9.75 GB/s | 🟢▲ +0.22% | 2.30% |
| unidirectional_lockless/4096 | iocp | bytes_per_sec | 1.10 GB/s | 1.10 GB/s | 🔴▼ -0.03% | 0.54% |
| unidirectional_lockless/65536 | iocp | bytes_per_sec | 9.21 GB/s | 9.39 GB/s | ⚪ 0.00% | 3.99% |
macos — full results (113 benchmarks, 5 iterations, 1.5s each)
accept_churn
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| burst/10 | kqueue | ops_per_sec | 4.26K ops/s | 4.40K ops/s | 🟢▲ +2.84% | 1.13% |
| burst/100 | kqueue | ops_per_sec | 431.9 ops/s | 443.3 ops/s | 🟢▲ +3.36% | 0.81% |
| burst_lockless/10 | kqueue | ops_per_sec | 4.28K ops/s | 4.40K ops/s | 🟢▲ +2.88% | 0.98% |
| burst_lockless/100 | kqueue | ops_per_sec | 436.2 ops/s | 452.3 ops/s | 🟢▲ +3.25% | 1.35% |
| concurrent/1 | kqueue | ops_per_sec | 19.58K ops/s | 20.18K ops/s | 🟢▲ +3.49% | 1.03% |
| concurrent/16 | kqueue | ops_per_sec | 35.63K ops/s | 36.46K ops/s | 🟢▲ +2.65% | 1.14% |
| concurrent/4 | kqueue | ops_per_sec | 29.10K ops/s | 29.24K ops/s | 🔴▼ -0.08% | 0.86% |
| sequential | kqueue | ops_per_sec | 19.88K ops/s | 20.37K ops/s | 🟢▲ +2.21% | 0.74% |
| sequential_lockless | kqueue | ops_per_sec | 19.80K ops/s | 20.14K ops/s | 🟢▲ +1.86% | 1.20% |
fan_out
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent_parents/1 | kqueue | ops_per_sec | 7.67K ops/s | 7.69K ops/s | 🔴▼ -0.04% | 1.08% |
| concurrent_parents/16 | kqueue | ops_per_sec | 7.99K ops/s | 8.04K ops/s | 🔴▼ -0.23% | 14.60% |
| concurrent_parents/4 | kqueue | ops_per_sec | 8.13K ops/s | 8.06K ops/s | 🔴▼ -0.32% | 1.82% |
| concurrent_parents_lockless/1 | kqueue | ops_per_sec | 7.74K ops/s | 7.73K ops/s | 🔴▼ -0.11% | 1.18% |
| concurrent_parents_lockless/16 | kqueue | ops_per_sec | 8.08K ops/s | 8.05K ops/s | 🟢▲ +0.39% | 14.77% |
| concurrent_parents_lockless/4 | kqueue | ops_per_sec | 8.15K ops/s | 8.14K ops/s | 🔴▼ -0.03% | 1.58% |
| fork_join/1 | kqueue | ops_per_sec | 45.79K ops/s | 45.79K ops/s | 🟢▲ +0.43% | 1.26% |
| fork_join/16 | kqueue | ops_per_sec | 7.69K ops/s | 7.69K ops/s | 🔴▼ -0.06% | 1.18% |
| fork_join/4 | kqueue | ops_per_sec | 21.71K ops/s | 21.81K ops/s | 🟢▲ +0.69% | 0.51% |
| fork_join/64 | kqueue | ops_per_sec | 2.02K ops/s | 2.02K ops/s | 🟢▲ +0.28% | 2.47% |
| fork_join_lockless/1 | kqueue | ops_per_sec | 47.00K ops/s | 46.91K ops/s | 🔴▼ -0.19% | 0.08% |
| fork_join_lockless/16 | kqueue | ops_per_sec | 7.74K ops/s | 7.74K ops/s | 🔴▼ -0.24% | 1.34% |
| fork_join_lockless/4 | kqueue | ops_per_sec | 21.90K ops/s | 21.88K ops/s | 🟢▲ +0.19% | 0.53% |
| fork_join_lockless/64 | kqueue | ops_per_sec | 2.03K ops/s | 2.02K ops/s | 🔴▼ -0.11% | 2.48% |
| nested/16 | kqueue | ops_per_sec | 2.00K ops/s | 1.99K ops/s | 🔴▼ -0.08% | 1.79% |
| nested/4 | kqueue | ops_per_sec | 7.06K ops/s | 7.06K ops/s | 🔴▼ -0.06% | 0.92% |
| nested_lockless/16 | kqueue | ops_per_sec | 2.01K ops/s | 2.00K ops/s | 🟢▲ +0.69% | 2.41% |
| nested_lockless/4 | kqueue | ops_per_sec | 7.15K ops/s | 7.13K ops/s | 🔴▼ -0.50% | 1.25% |
http_server
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | kqueue | ops_per_sec | 49.59K ops/s | 49.25K ops/s | 🔴▼ -0.42% | 0.38% |
| concurrent/16 | kqueue | ops_per_sec | 127.3K ops/s | 129.0K ops/s | 🟢▲ +1.19% | 0.69% |
| concurrent/32 | kqueue | ops_per_sec | 127.0K ops/s | 128.8K ops/s | 🟢▲ +1.50% | 1.41% |
| concurrent/4 | kqueue | ops_per_sec | 88.02K ops/s | 88.77K ops/s | 🟢▲ +0.87% | 0.55% |
| multithread/1 | kqueue | ops_per_sec | 126.8K ops/s | 128.4K ops/s | 🟢▲ +0.84% | 1.29% |
| multithread/16 | kqueue | ops_per_sec | 127.3K ops/s | 127.5K ops/s | 🔴▼ -0.14% | 0.67% |
| multithread/2 | kqueue | ops_per_sec | 176.9K ops/s | 177.2K ops/s | 🟢▲ +0.42% | 1.77% |
| multithread/4 | kqueue | ops_per_sec | 160.8K ops/s | 161.5K ops/s | 🟢▲ +0.38% | 1.01% |
| multithread/8 | kqueue | ops_per_sec | 132.6K ops/s | 132.0K ops/s | 🔴▼ -1.40% | 1.62% |
| single_conn | kqueue | ops_per_sec | 49.65K ops/s | 49.34K ops/s | 🔴▼ -0.47% | 0.27% |
| single_conn_lockless | kqueue | ops_per_sec | 49.80K ops/s | 49.51K ops/s | 🔴▼ -0.59% | 0.34% |
local_socket_latency
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | kqueue | latency_mean_ns | 2.06 µs | 2.06 µs | 🔴▼ -0.10% | 0.24% |
| concurrent/16 | kqueue | latency_mean_ns | 30.64 µs | 30.53 µs | 🟢▲ +0.16% | 0.32% |
| concurrent/4 | kqueue | latency_mean_ns | 7.66 µs | 7.65 µs | 🟢▲ +0.29% | 0.37% |
| concurrent_lockless/1 | kqueue | latency_mean_ns | 2.02 µs | 2.04 µs | 🔴▼ -0.89% | 0.45% |
| concurrent_lockless/16 | kqueue | latency_mean_ns | 30.13 µs | 30.11 µs | 🟢▲ +0.04% | 0.27% |
| concurrent_lockless/4 | kqueue | latency_mean_ns | 7.54 µs | 7.54 µs | 🔴▼ -0.05% | 0.37% |
| pingpong/1 | kqueue | latency_mean_ns | 2.05 µs | 2.06 µs | 🔴▼ -0.54% | 0.49% |
| pingpong/1024 | kqueue | latency_mean_ns | 2.16 µs | 2.16 µs | 🟢▲ +0.14% | 0.34% |
| pingpong/64 | kqueue | latency_mean_ns | 2.05 µs | 2.06 µs | 🔴▼ -0.07% | 0.31% |
| pingpong_lockless/1 | kqueue | latency_mean_ns | 2.02 µs | 2.03 µs | 🔴▼ -0.42% | 0.64% |
| pingpong_lockless/1024 | kqueue | latency_mean_ns | 2.13 µs | 2.13 µs | 🔴▼ -0.29% | 0.14% |
| pingpong_lockless/64 | kqueue | latency_mean_ns | 2.02 µs | 2.03 µs | 🔴▼ -0.23% | 0.33% |
local_socket_throughput
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| bidirectional/1024 | kqueue | bytes_per_sec | 1.22 GB/s | 1.22 GB/s | 🔴▼ -0.01% | 0.32% |
| bidirectional/1048576 | kqueue | bytes_per_sec | 3.85 GB/s | 3.86 GB/s | 🟢▲ +0.41% | 0.38% |
| bidirectional/16384 | kqueue | bytes_per_sec | 3.85 GB/s | 3.87 GB/s | 🔴▼ -0.07% | 1.12% |
| bidirectional/262144 | kqueue | bytes_per_sec | 3.86 GB/s | 3.86 GB/s | 🟢▲ +0.44% | 0.94% |
| bidirectional/4096 | kqueue | bytes_per_sec | 2.91 GB/s | 2.92 GB/s | 🟢▲ +0.15% | 0.65% |
| bidirectional/65536 | kqueue | bytes_per_sec | 3.86 GB/s | 3.86 GB/s | 🔴▼ -0.60% | 1.05% |
| bidirectional_lockless/1024 | kqueue | bytes_per_sec | 1.23 GB/s | 1.23 GB/s | 🔴▼ -0.34% | 0.44% |
| bidirectional_lockless/1048576 | kqueue | bytes_per_sec | 3.90 GB/s | 3.92 GB/s | 🟢▲ +0.13% | 0.83% |
| bidirectional_lockless/16384 | kqueue | bytes_per_sec | 3.92 GB/s | 3.91 GB/s | 🔴▼ -0.11% | 0.41% |
| bidirectional_lockless/262144 | kqueue | bytes_per_sec | 3.91 GB/s | 3.91 GB/s | 🟢▲ +0.22% | 0.81% |
| bidirectional_lockless/4096 | kqueue | bytes_per_sec | 2.96 GB/s | 2.94 GB/s | 🔴▼ -0.45% | 0.38% |
| bidirectional_lockless/65536 | kqueue | bytes_per_sec | 3.92 GB/s | 3.90 GB/s | 🔴▼ -0.42% | 0.75% |
| unidirectional/1024 | kqueue | bytes_per_sec | 1.19 GB/s | 1.19 GB/s | 🟢▲ +0.09% | 0.44% |
| unidirectional/1048576 | kqueue | bytes_per_sec | 3.46 GB/s | 3.46 GB/s | 🟢▲ +0.01% | 0.28% |
| unidirectional/16384 | kqueue | bytes_per_sec | 3.46 GB/s | 3.47 GB/s | 🟢▲ +0.26% | 0.36% |
| unidirectional/262144 | kqueue | bytes_per_sec | 3.46 GB/s | 3.46 GB/s | 🔴▼ -0.47% | 0.70% |
| unidirectional/4096 | kqueue | bytes_per_sec | 2.68 GB/s | 2.69 GB/s | 🟢▲ +0.40% | 0.47% |
| unidirectional/65536 | kqueue | bytes_per_sec | 3.46 GB/s | 3.47 GB/s | 🟢▲ +0.40% | 0.34% |
| unidirectional_lockless/1024 | kqueue | bytes_per_sec | 1.20 GB/s | 1.20 GB/s | 🔴▼ -0.18% | 0.47% |
| unidirectional_lockless/1048576 | kqueue | bytes_per_sec | 3.50 GB/s | 3.51 GB/s | 🟢▲ +0.32% | 0.31% |
| unidirectional_lockless/16384 | kqueue | bytes_per_sec | 3.52 GB/s | 3.53 GB/s | 🟢▲ +0.38% | 0.41% |
| unidirectional_lockless/262144 | kqueue | bytes_per_sec | 3.51 GB/s | 3.51 GB/s | 🟢▲ +0.07% | 0.34% |
| unidirectional_lockless/4096 | kqueue | bytes_per_sec | 2.73 GB/s | 2.72 GB/s | 🔴▼ -0.40% | 0.26% |
| unidirectional_lockless/65536 | kqueue | bytes_per_sec | 3.52 GB/s | 3.52 GB/s | 🟢▲ +0.16% | 0.51% |
socket_latency
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| concurrent/1 | kqueue | latency_mean_ns | 18.80 µs | 18.78 µs | 🔴▼ -0.05% | 0.66% |
| concurrent/16 | kqueue | latency_mean_ns | 120.23 µs | 120.56 µs | 🔴▼ -0.15% | 0.29% |
| concurrent/4 | kqueue | latency_mean_ns | 43.35 µs | 43.49 µs | 🔴▼ -0.54% | 1.06% |
| concurrent_lockless/1 | kqueue | latency_mean_ns | 18.66 µs | 18.76 µs | 🔴▼ -0.71% | 0.45% |
| concurrent_lockless/16 | kqueue | latency_mean_ns | 119.68 µs | 120.07 µs | 🔴▼ -0.53% | 0.69% |
| concurrent_lockless/4 | kqueue | latency_mean_ns | 43.07 µs | 43.07 µs | 🔴▼ -0.08% | 0.45% |
| pingpong/1 | kqueue | latency_mean_ns | 15.45 µs | 15.50 µs | 🔴▼ -0.15% | 0.80% |
| pingpong/1024 | kqueue | latency_mean_ns | 18.90 µs | 18.95 µs | 🔴▼ -0.12% | 0.30% |
| pingpong/64 | kqueue | latency_mean_ns | 18.72 µs | 18.77 µs | 🔴▼ -0.29% | 0.50% |
| pingpong_lockless/1 | kqueue | latency_mean_ns | 15.40 µs | 15.47 µs | 🔴▼ -0.22% | 0.79% |
| pingpong_lockless/1024 | kqueue | latency_mean_ns | 18.93 µs | 18.94 µs | 🟢▲ +0.03% | 0.35% |
| pingpong_lockless/64 | kqueue | latency_mean_ns | 18.67 µs | 18.74 µs | 🔴▼ -0.33% | 0.50% |
socket_throughput
| Benchmark | Backend | Metric | Base | Head | Δ | Noise |
|---|---|---|---|---|---|---|
| bidirectional/1024 | kqueue | bytes_per_sec | 410.5 MB/s | 408.7 MB/s | 🟢▲ +0.10% | 0.79% |
| bidirectional/1048576 | kqueue | bytes_per_sec | 7.78 GB/s | 7.54 GB/s | 🔴▼ -0.77% | 4.87% |
| bidirectional/16384 | kqueue | bytes_per_sec | 3.99 GB/s | 3.98 GB/s | 🔴▼ -0.39% | 0.62% |
| bidirectional/262144 | kqueue | bytes_per_sec | 8.74 GB/s | 8.68 GB/s | 🔴▼ -0.63% | 1.47% |
| bidirectional/4096 | kqueue | bytes_per_sec | 1.49 GB/s | 1.49 GB/s | 🔴▼ -0.01% | 0.65% |
| bidirectional/65536 | kqueue | bytes_per_sec | 7.53 GB/s | 7.51 GB/s | 🟢▲ +0.80% | 1.91% |
| bidirectional_lockless/1024 | kqueue | bytes_per_sec | 414.1 MB/s | 410.3 MB/s | 🔴▼ -0.63% | 0.79% |
| bidirectional_lockless/1048576 | kqueue | bytes_per_sec | 7.79 GB/s | 7.68 GB/s | 🔴▼ -1.00% | 6.56% |
| bidirectional_lockless/16384 | kqueue | bytes_per_sec | 4.00 GB/s | 4.01 GB/s | 🟢▲ +0.82% | 0.86% |
| bidirectional_lockless/262144 | kqueue | bytes_per_sec | 8.72 GB/s | 8.79 GB/s | 🟢▲ +1.21% | 1.63% |
| bidirectional_lockless/4096 | kqueue | bytes_per_sec | 1.50 GB/s | 1.50 GB/s | 🔴▼ -0.46% | 0.75% |
| bidirectional_lockless/65536 | kqueue | bytes_per_sec | 7.59 GB/s | 7.66 GB/s | 🟢▲ +1.05% | 1.18% |
| multithread/2 | kqueue | bytes_per_sec | 7.68 GB/s | 7.57 GB/s | 🟢▲ +1.04% | 3.08% |
| multithread/4 | kqueue | bytes_per_sec | 3.83 GB/s | 3.71 GB/s | 🔴▼ -1.62% | 5.39% |
| multithread/8 | kqueue | bytes_per_sec | 3.30 GB/s | 3.29 GB/s | 🔴▼ -3.22% | 5.20% |
| unidirectional/1024 | kqueue | bytes_per_sec | 317.7 MB/s | 316.7 MB/s | 🔴▼ -0.45% | 1.05% |
| unidirectional/1048576 | kqueue | bytes_per_sec | 9.04 GB/s | 8.78 GB/s | 🔴▼ -0.33% | 5.69% |
| unidirectional/16384 | kqueue | bytes_per_sec | 3.71 GB/s | 3.70 GB/s | 🔴▼ -0.25% | 0.50% |
| unidirectional/262144 | kqueue | bytes_per_sec | 8.82 GB/s | 8.83 GB/s | 🔴▼ -0.74% | 3.57% |
| unidirectional/4096 | kqueue | bytes_per_sec | 1.23 GB/s | 1.24 GB/s | 🟢▲ +0.08% | 1.71% |
| unidirectional/65536 | kqueue | bytes_per_sec | 7.26 GB/s | 7.23 GB/s | 🟢▲ +0.20% | 2.01% |
| unidirectional_lockless/1024 | kqueue | bytes_per_sec | 327.9 MB/s | 327.2 MB/s | 🔴▼ -0.02% | 0.38% |
| unidirectional_lockless/1048576 | kqueue | bytes_per_sec | 9.03 GB/s | 8.85 GB/s | 🟢▲ +0.14% | 5.30% |
| unidirectional_lockless/16384 | kqueue | bytes_per_sec | 3.73 GB/s | 3.74 GB/s | 🟢▲ +0.19% | 1.17% |
| unidirectional_lockless/262144 | kqueue | bytes_per_sec | 8.85 GB/s | 8.79 GB/s | 🔴▼ -1.19% | 0.98% |
| unidirectional_lockless/4096 | kqueue | bytes_per_sec | 1.25 GB/s | 1.24 GB/s | 🔴▼ -0.57% | 1.42% |
| unidirectional_lockless/65536 | kqueue | bytes_per_sec | 7.21 GB/s | 7.20 GB/s | 🔴▼ -0.54% | 2.13% |
Run & raw JSON artifacts · flag rule: |median Δ| > max(2%, 3×CV of the noisier side) · advisory only
Replaces per-impl
shared_ptrownership with an intrusive refcount(
object_ref) and a per-service recycling pool (object_pool), thenextends recycling to the remaining per-operation allocations. Once
warmed, construct/destroy, accept, positional file I/O, timer waits,
and
tcp_serverconnection dispatch allocate nothing.Changes
object_pool<Impl>/object_ref: live/free intrusive lists behindone mutex, variadic
acquire()as the library's onlynewsite forimpls,
retire()at the zero-crossing recycles instead of deleting.All backends converted; IOCP's wrapper/internal split collapsed;
timer unified (keeping its thread-local slot).
waiter_node+ per-completion op merged intoone pooled
accept_node(2 heap nodes per accept -> 0).uring, and IOCP (~500 B malloc/free per read/write -> 0).
tcp_serverlaunch: reused workerstop_source, pooled launchframe, post via frame-embedded continuation.
deferring executor the op's embedded continuation, which its queue
holds by reference while the op is recycled/reused/freed --
use-after-free or corrupted resume on every backend.
dispatch_coronow lends a self-destroying trampoline frameinstead; the io_context fast path is unchanged. Includes
deterministic multi-executor regression tests.
loud-skip otherwise (Valgrind replaces the allocator at run time).
__interceptor_exports so ASan/TSan thread bookkeeping survivesinterception (clang >= 23 link-order change).
Verification
accept/echo/close, impl reuse,
delay(), raf write+read, andtcp_server churn at 0/cycle on epoll and uring (select keeps its
documented 2/cycle descriptor-map cost).
uring +1.2-2.2% measured before the accept-node pooling that removes
its remaining per-accept allocations.
full CI matrix green; ASan/TSan clean.
Resolves #381.