Skip to content

Add native descriptor and handle types - #386

Merged
sgerbino merged 1 commit into
cppalliance:developfrom
mvandeberg:pr/native-descriptors
Oct 9, 2026
Merged

sgerbino merged 1 commit into
cppalliance:developfrom
mvandeberg:pr/native-descriptors

Conversation

@mvandeberg

Copy link
Copy Markdown
Contributor

Add types that adopt an open native resource into an io_context:

  • posix_stream_descriptor: a stream for a pollable descriptor, such as a pipe, a tty, eventfd, timerfd, inotify or pidfd. It works on epoll, kqueue, select and io_uring.
  • win_stream_handle: a stream for an overlapped Windows handle, such as a named pipe or a COM port.
  • win_random_access_handle: positional I/O for an overlapped Windows handle, such as a volume.
  • win_object_handle: a wait for a Windows kernel object. Processes, threads, events, semaphores, waitable timers and jobs are accepted.

assign() rejects a resource that the type cannot use. If the object is open, assign() returns error::already_open and does not change the object. This applies to all types that adopt a handle, and to connect_pair().

POSIX:

  • Sockets, acceptors and descriptors share one reactor base for register, park, cancel and close.
  • The reactors set O_NONBLOCK at the first read or write. assign() and wait() do not change the descriptor. io_uring does not set O_NONBLOCK.
  • wait() examines readiness with poll(). wait(read) and wait(write) report readiness on an error or a hangup and do not read SO_ERROR.
  • kqueue watches writes only when a write must first wait.
  • select watches a descriptor only while an operation waits on it.
  • A descriptor that the kernel cannot poll is adopted. On epoll, kqueue and io_uring, an operation that must wait on it completes with operation_not_supported. select treats it as always ready.
  • File I/O uses 64-bit offsets in 32-bit builds.
  • release() on a file cancels the pending operations.

Windows:

  • stream_file, random_access_file and the two overlapped handle types use one overlapped handle core.
  • release() cancels the pending operations and removes the handle from the completion port. If an operation is in progress, or Windows refuses, release() throws and the object keeps the handle.
  • The stream_file position moves by the bytes transferred. A completion from an earlier handle does not move it.
  • win_object_handle waits through the Windows thread pool. A wait that the kernel satisfied always reports success.
  • wait(read) and wait(write) on a socket report readiness. Only wait(error) reads SO_ERROR.

Add the "Native Descriptors and Handles" guide page and reference examples for win_random_access_handle. Update the file I/O, wait, error handling and configuration pages.

Refs #338.

@cppalliance-bot

cppalliance-bot commented Oct 7, 2026 •

Copy link
Copy Markdown

GCOVR code coverage report https://386.corosio.prtest3.cppalliance.org/gcovr/index.html
LCOV code coverage report https://386.corosio.prtest3.cppalliance.org/genhtml/index.html
Coverage Diff Report https://386.corosio.prtest3.cppalliance.org/diff-report/index.html

Build time: 2026-10-08 18:06:49 UTC

@mvandeberg
mvandeberg force-pushed the pr/native-descriptors branch from 1d2e440 to 56ce5c3 Compare October 7, 2026 17:28
@cppalliance-bot

cppalliance-bot commented Oct 7, 2026 •

Copy link
Copy Markdown

An automated preview of the documentation is available at https://386.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 17:49:39 UTC

@mvandeberg
mvandeberg marked this pull request as ready for review October 7, 2026 20:47
@sgerbino sgerbino added the benchmark Triggers benchmark suite label Oct 7, 2026
@github-actions github-actions Bot removed the benchmark Triggers benchmark suite label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Benchmark report

15339147af84 (base) vs c3f871560a6f (head)

  • ✅ linux — clean (epoll, uring)
  • ✅ windows — clean (iocp)
  • ⚠️ macos — 41 flagged (kqueue)

⚠️ Flagged

Platform Backend Benchmark Metric Base Head Δ Noise
macos kqueue fan_out/concurrent_parents/1 ops_per_sec 7.72K ops/s 8.05K ops/s 🟢▲ +4.30% 0.63%
macos kqueue fan_out/concurrent_parents_lockless/1 ops_per_sec 7.78K ops/s 8.10K ops/s 🟢▲ +4.26% 0.76%
macos kqueue fan_out/fork_join/1 ops_per_sec 45.94K ops/s 48.93K ops/s 🟢▲ +6.21% 0.64%
macos kqueue fan_out/fork_join/16 ops_per_sec 7.72K ops/s 8.03K ops/s 🟢▲ +4.14% 0.63%
macos kqueue fan_out/fork_join/4 ops_per_sec 21.70K ops/s 23.69K ops/s 🟢▲ +9.06% 0.64%
macos kqueue fan_out/fork_join_lockless/1 ops_per_sec 46.84K ops/s 50.04K ops/s 🟢▲ +6.56% 0.67%
macos kqueue fan_out/fork_join_lockless/16 ops_per_sec 7.79K ops/s 8.12K ops/s 🟢▲ +4.40% 0.90%
macos kqueue fan_out/fork_join_lockless/4 ops_per_sec 21.87K ops/s 23.73K ops/s 🟢▲ +8.25% 0.76%
macos kqueue fan_out/nested/4 ops_per_sec 7.09K ops/s 7.97K ops/s 🟢▲ +12.48% 0.48%
macos kqueue fan_out/nested_lockless/4 ops_per_sec 7.19K ops/s 8.06K ops/s 🟢▲ +12.12% 0.78%
macos kqueue http_server/multithread/16 ops_per_sec 128.1K ops/s 133.7K ops/s 🟢▲ +5.01% 1.04%
macos kqueue http_server/multithread/2 ops_per_sec 175.7K ops/s 185.5K ops/s 🟢▲ +5.70% 1.55%
macos kqueue http_server/multithread/8 ops_per_sec 131.8K ops/s 137.6K ops/s 🟢▲ +4.02% 1.25%
macos kqueue local_socket_latency/concurrent/1 latency_mean_ns 2.06 µs 1.84 µs 🟢▲ +10.90% 0.31%
macos kqueue local_socket_latency/concurrent/16 latency_mean_ns 30.63 µs 27.19 µs 🟢▲ +11.12% 0.49%
macos kqueue local_socket_latency/concurrent/4 latency_mean_ns 7.68 µs 6.83 µs 🟢▲ +11.14% 0.54%
macos kqueue local_socket_latency/concurrent_lockless/1 latency_mean_ns 2.03 µs 1.82 µs 🟢▲ +10.21% 0.27%
macos kqueue local_socket_latency/concurrent_lockless/16 latency_mean_ns 30.19 µs 26.93 µs 🟢▲ +10.72% 0.31%
macos kqueue local_socket_latency/concurrent_lockless/4 latency_mean_ns 7.55 µs 6.78 µs 🟢▲ +10.35% 0.49%
macos kqueue local_socket_latency/pingpong/1 latency_mean_ns 2.05 µs 1.83 µs 🟢▲ +10.77% 0.35%
macos kqueue local_socket_latency/pingpong/1024 latency_mean_ns 2.16 µs 1.93 µs 🟢▲ +10.87% 0.50%
macos kqueue local_socket_latency/pingpong/64 latency_mean_ns 2.06 µs 1.84 µs 🟢▲ +10.50% 0.25%
macos kqueue local_socket_latency/pingpong_lockless/1 latency_mean_ns 2.03 µs 1.82 µs 🟢▲ +10.31% 0.38%
macos kqueue local_socket_latency/pingpong_lockless/1024 latency_mean_ns 2.13 µs 1.91 µs 🟢▲ +10.22% 0.69%
macos kqueue local_socket_latency/pingpong_lockless/64 latency_mean_ns 2.02 µs 1.82 µs 🟢▲ +10.11% 0.40%
macos kqueue local_socket_throughput/bidirectional/1024 bytes_per_sec 1.22 GB/s 1.30 GB/s 🟢▲ +6.89% 0.66%
macos kqueue local_socket_throughput/bidirectional_lockless/1024 bytes_per_sec 1.23 GB/s 1.31 GB/s 🟢▲ +6.62% 0.86%
macos kqueue local_socket_throughput/unidirectional/1024 bytes_per_sec 1.19 GB/s 1.28 GB/s 🟢▲ +7.45% 0.83%
macos kqueue local_socket_throughput/unidirectional_lockless/1024 bytes_per_sec 1.20 GB/s 1.28 GB/s 🟢▲ +7.09% 1.25%
macos kqueue socket_throughput/bidirectional/1024 bytes_per_sec 408.2 MB/s 470.8 MB/s 🟢▲ +14.88% 0.71%
macos kqueue socket_throughput/bidirectional/16384 bytes_per_sec 3.98 GB/s 4.51 GB/s 🟢▲ +12.66% 1.22%
macos kqueue socket_throughput/bidirectional/4096 bytes_per_sec 1.49 GB/s 1.82 GB/s 🟢▲ +22.15% 0.33%
macos kqueue socket_throughput/bidirectional_lockless/1024 bytes_per_sec 411.8 MB/s 472.7 MB/s 🟢▲ +14.19% 0.89%
macos kqueue socket_throughput/bidirectional_lockless/16384 bytes_per_sec 4.01 GB/s 4.56 GB/s 🟢▲ +14.07% 1.21%
macos kqueue socket_throughput/bidirectional_lockless/4096 bytes_per_sec 1.51 GB/s 1.82 GB/s 🟢▲ +20.55% 1.49%
macos kqueue socket_throughput/unidirectional/1024 bytes_per_sec 317.5 MB/s 458.0 MB/s 🟢▲ +44.26% 0.66%
macos kqueue socket_throughput/unidirectional/16384 bytes_per_sec 3.71 GB/s 4.42 GB/s 🟢▲ +18.99% 1.61%
macos kqueue socket_throughput/unidirectional/4096 bytes_per_sec 1.25 GB/s 1.80 GB/s 🟢▲ +44.55% 1.91%
macos kqueue socket_throughput/unidirectional_lockless/1024 bytes_per_sec 326.6 MB/s 473.7 MB/s 🟢▲ +45.23% 0.51%
macos kqueue socket_throughput/unidirectional_lockless/16384 bytes_per_sec 3.73 GB/s 4.51 GB/s 🟢▲ +21.14% 1.59%
macos kqueue socket_throughput/unidirectional_lockless/4096 bytes_per_sec 1.25 GB/s 1.80 GB/s 🟢▲ +44.42% 0.76%
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.88K ops/s 🔴▼ -0.28% 0.83%
burst/10 uring ops_per_sec 1.70K ops/s 1.71K ops/s 🟢▲ +0.04% 0.97%
burst/100 epoll ops_per_sec 189.4 ops/s 189.2 ops/s 🟢▲ +0.06% 0.78%
burst/100 uring ops_per_sec 174.0 ops/s 174.0 ops/s 🟢▲ +0.14% 0.66%
burst_lockless/10 epoll ops_per_sec 1.89K ops/s 1.88K ops/s 🔴▼ -0.29% 0.94%
burst_lockless/10 uring ops_per_sec 1.82K ops/s 1.83K ops/s 🟢▲ +0.12% 0.96%
burst_lockless/100 epoll ops_per_sec 189.9 ops/s 189.6 ops/s 🔴▼ -0.25% 0.36%
burst_lockless/100 uring ops_per_sec 186.0 ops/s 186.2 ops/s 🟢▲ +0.37% 0.74%
concurrent/1 epoll ops_per_sec 14.96K ops/s 15.04K ops/s 🟢▲ +0.46% 0.80%
concurrent/1 uring ops_per_sec 12.67K ops/s 12.75K ops/s 🟢▲ +0.61% 0.98%
concurrent/16 epoll ops_per_sec 15.00K ops/s 14.96K ops/s 🔴▼ -0.51% 0.84%
concurrent/16 uring ops_per_sec 12.54K ops/s 12.62K ops/s 🟢▲ +0.43% 0.80%
concurrent/4 epoll ops_per_sec 14.97K ops/s 14.95K ops/s 🔴▼ -0.46% 0.83%
concurrent/4 uring ops_per_sec 12.63K ops/s 12.71K ops/s 🟢▲ +0.51% 1.17%
sequential epoll ops_per_sec 14.91K ops/s 15.03K ops/s 🟢▲ +0.51% 0.86%
sequential uring ops_per_sec 12.70K ops/s 12.72K ops/s 🟢▲ +0.02% 0.84%
sequential_lockless epoll ops_per_sec 15.00K ops/s 15.15K ops/s 🟢▲ +0.83% 0.78%
sequential_lockless uring ops_per_sec 13.63K ops/s 13.62K ops/s 🔴▼ -0.45% 0.86%

fan_out

Benchmark Backend Metric Base Head Δ Noise
concurrent_parents/1 epoll ops_per_sec 3.70K ops/s 3.68K ops/s 🔴▼ -0.31% 0.77%
concurrent_parents/1 uring ops_per_sec 3.43K ops/s 3.44K ops/s 🔴▼ -0.07% 1.09%
concurrent_parents/16 epoll ops_per_sec 3.57K ops/s 3.57K ops/s 🔴▼ -0.20% 0.23%
concurrent_parents/16 uring ops_per_sec 3.32K ops/s 3.31K ops/s 🔴▼ -0.51% 1.08%
concurrent_parents/4 epoll ops_per_sec 3.59K ops/s 3.58K ops/s 🔴▼ -0.02% 0.14%
concurrent_parents/4 uring ops_per_sec 3.35K ops/s 3.34K ops/s 🔴▼ -0.25% 1.17%
concurrent_parents_lockless/1 epoll ops_per_sec 3.73K ops/s 3.72K ops/s 🔴▼ -0.26% 0.22%
concurrent_parents_lockless/1 uring ops_per_sec 3.67K ops/s 3.66K ops/s 🔴▼ -0.19% 1.18%
concurrent_parents_lockless/16 epoll ops_per_sec 3.61K ops/s 3.61K ops/s 🟢▲ +0.09% 0.22%
concurrent_parents_lockless/16 uring ops_per_sec 3.53K ops/s 3.51K ops/s 🔴▼ -0.16% 1.11%
concurrent_parents_lockless/4 epoll ops_per_sec 3.62K ops/s 3.62K ops/s 🔴▼ -0.14% 0.32%
concurrent_parents_lockless/4 uring ops_per_sec 3.56K ops/s 3.54K ops/s 🔴▼ -0.30% 0.99%
fork_join/1 epoll ops_per_sec 54.59K ops/s 54.64K ops/s 🟢▲ +0.21% 0.23%
fork_join/1 uring ops_per_sec 53.54K ops/s 53.28K ops/s 🔴▼ -0.28% 1.25%
fork_join/16 epoll ops_per_sec 3.69K ops/s 3.68K ops/s 🔴▼ -0.02% 0.34%
fork_join/16 uring ops_per_sec 3.45K ops/s 3.43K ops/s 🔴▼ -0.41% 1.08%
fork_join/4 epoll ops_per_sec 14.61K ops/s 14.62K ops/s 🟢▲ +0.06% 0.20%
fork_join/4 uring ops_per_sec 13.79K ops/s 13.73K ops/s 🔴▼ -0.54% 1.16%
fork_join/64 epoll ops_per_sec 900.8 ops/s 897.5 ops/s 🔴▼ -0.07% 1.03%
fork_join/64 uring ops_per_sec 816.1 ops/s 809.1 ops/s 🔴▼ -0.42% 1.12%
fork_join_lockless/1 epoll ops_per_sec 55.75K ops/s 55.57K ops/s 🔴▼ -0.38% 0.93%
fork_join_lockless/1 uring ops_per_sec 56.12K ops/s 55.77K ops/s 🔴▼ -0.09% 0.93%
fork_join_lockless/16 epoll ops_per_sec 3.76K ops/s 3.74K ops/s 🔴▼ -0.20% 1.26%
fork_join_lockless/16 uring ops_per_sec 3.65K ops/s 3.65K ops/s 🟢▲ +0.03% 0.20%
fork_join_lockless/4 epoll ops_per_sec 14.86K ops/s 14.88K ops/s 🟢▲ +0.05% 1.01%
fork_join_lockless/4 uring ops_per_sec 14.61K ops/s 14.54K ops/s 🔴▼ -0.34% 0.49%
fork_join_lockless/64 epoll ops_per_sec 914.6 ops/s 910.3 ops/s 🔴▼ -0.54% 1.17%
fork_join_lockless/64 uring ops_per_sec 863.5 ops/s 865.1 ops/s 🟢▲ +0.22% 0.23%
nested/16 epoll ops_per_sec 896.3 ops/s 894.7 ops/s 🔴▼ -0.11% 1.03%
nested/16 uring ops_per_sec 802.3 ops/s 804.6 ops/s 🟢▲ +0.21% 0.53%
nested/4 epoll ops_per_sec 3.69K ops/s 3.67K ops/s 🔴▼ -0.18% 1.25%
nested/4 uring ops_per_sec 3.39K ops/s 3.39K ops/s 🔴▼ -0.17% 0.24%
nested_lockless/16 epoll ops_per_sec 903.8 ops/s 901.3 ops/s 🔴▼ -0.13% 1.08%
nested_lockless/16 uring ops_per_sec 853.6 ops/s 858.6 ops/s 🟢▲ +0.27% 0.92%
nested_lockless/4 epoll ops_per_sec 3.72K ops/s 3.72K ops/s 🔴▼ -0.20% 1.07%
nested_lockless/4 uring ops_per_sec 3.61K ops/s 3.63K ops/s 🟢▲ +0.05% 1.08%

http_server

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 epoll ops_per_sec 55.21K ops/s 55.31K ops/s 🟢▲ +0.26% 1.06%
concurrent/1 uring ops_per_sec 53.90K ops/s 53.59K ops/s 🔴▼ -0.50% 1.05%
concurrent/16 epoll ops_per_sec 57.59K ops/s 57.79K ops/s 🟢▲ +0.21% 0.50%
concurrent/16 uring ops_per_sec 53.18K ops/s 53.10K ops/s 🔴▼ -0.01% 1.30%
concurrent/32 epoll ops_per_sec 57.25K ops/s 57.34K ops/s 🟢▲ +0.15% 0.30%
concurrent/32 uring ops_per_sec 52.79K ops/s 52.70K ops/s 🔴▼ -0.23% 1.29%
concurrent/4 epoll ops_per_sec 57.03K ops/s 57.33K ops/s 🟢▲ +0.10% 1.00%
concurrent/4 uring ops_per_sec 53.32K ops/s 53.07K ops/s 🔴▼ -0.24% 1.25%
multithread/1 epoll ops_per_sec 57.18K ops/s 57.32K ops/s 🟢▲ +0.20% 0.23%
multithread/1 uring ops_per_sec 52.78K ops/s 52.70K ops/s 🟢▲ +0.04% 1.26%
multithread/16 epoll ops_per_sec 162.4K ops/s 162.6K ops/s 🟢▲ +0.11% 0.36%
multithread/16 uring ops_per_sec 81.95K ops/s 81.99K ops/s 🔴▼ -0.07% 0.52%
multithread/2 epoll ops_per_sec 87.61K ops/s 86.66K ops/s 🔴▼ -0.97% 0.48%
multithread/2 uring ops_per_sec 89.64K ops/s 90.90K ops/s 🟢▲ +0.94% 0.82%
multithread/4 epoll ops_per_sec 159.0K ops/s 159.3K ops/s 🔴▼ -0.15% 1.15%
multithread/4 uring ops_per_sec 79.86K ops/s 80.05K ops/s 🟢▲ +0.03% 1.62%
multithread/8 epoll ops_per_sec 161.5K ops/s 161.9K ops/s 🟢▲ +0.22% 0.45%
multithread/8 uring ops_per_sec 77.49K ops/s 77.50K ops/s 🔴▼ -0.04% 0.20%
single_conn epoll ops_per_sec 55.31K ops/s 55.27K ops/s 🟢▲ +0.27% 1.12%
single_conn uring ops_per_sec 53.71K ops/s 53.41K ops/s 🔴▼ -0.55% 0.32%
single_conn_lockless epoll ops_per_sec 55.88K ops/s 55.93K ops/s 🟢▲ +0.04% 1.06%
single_conn_lockless uring ops_per_sec 56.56K ops/s 55.98K ops/s 🔴▼ -0.62% 1.25%

local_socket_latency

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 epoll latency_mean_ns 7.10 µs 7.12 µs 🔴▼ -0.61% 0.83%
concurrent/1 uring latency_mean_ns 6.56 µs 6.59 µs 🔴▼ -0.62% 0.85%
concurrent/16 epoll latency_mean_ns 109.99 µs 110.38 µs 🔴▼ -0.51% 0.78%
concurrent/16 uring latency_mean_ns 107.81 µs 108.14 µs 🔴▼ -0.48% 1.30%
concurrent/4 epoll latency_mean_ns 27.80 µs 27.72 µs 🔴▼ -0.23% 2.02%
concurrent/4 uring latency_mean_ns 26.97 µs 26.98 µs 🔴▼ -0.17% 1.33%
concurrent_lockless/1 epoll latency_mean_ns 7.16 µs 7.19 µs 🔴▼ -0.75% 4.39%
concurrent_lockless/1 uring latency_mean_ns 6.53 µs 6.83 µs 🔴▼ -0.94% 5.74%
concurrent_lockless/16 epoll latency_mean_ns 108.56 µs 109.50 µs 🔴▼ -0.60% 0.46%
concurrent_lockless/16 uring latency_mean_ns 107.41 µs 108.28 µs 🔴▼ -0.85% 0.90%
concurrent_lockless/4 epoll latency_mean_ns 27.42 µs 27.58 µs 🔴▼ -0.73% 1.50%
concurrent_lockless/4 uring latency_mean_ns 26.60 µs 27.01 µs 🔴▼ -1.38% 1.64%
pingpong/1 epoll latency_mean_ns 7.19 µs 7.22 µs 🔴▼ -0.40% 4.23%
pingpong/1 uring latency_mean_ns 6.47 µs 6.77 µs 🔴▼ -3.06% 5.08%
pingpong/1024 epoll latency_mean_ns 7.78 µs 7.83 µs 🔴▼ -0.35% 4.58%
pingpong/1024 uring latency_mean_ns 7.41 µs 7.33 µs 🔴▼ -0.68% 4.07%
pingpong/64 epoll latency_mean_ns 7.19 µs 7.41 µs 🔴▼ -1.01% 5.11%
pingpong/64 uring latency_mean_ns 6.78 µs 6.62 µs 🔴▼ -0.33% 5.13%
pingpong_lockless/1 epoll latency_mean_ns 6.96 µs 6.97 µs 🟢▲ +0.09% 0.48%
pingpong_lockless/1 uring latency_mean_ns 6.64 µs 6.70 µs 🔴▼ -0.45% 4.54%
pingpong_lockless/1024 epoll latency_mean_ns 7.65 µs 7.61 µs 🟢▲ +1.23% 4.96%
pingpong_lockless/1024 uring latency_mean_ns 6.88 µs 7.20 µs 🔴▼ -1.12% 5.26%
pingpong_lockless/64 epoll latency_mean_ns 7.01 µs 7.14 µs 🔴▼ -0.48% 4.59%
pingpong_lockless/64 uring latency_mean_ns 6.67 µs 6.71 µs 🔴▼ -0.57% 4.80%

local_socket_throughput

Benchmark Backend Metric Base Head Δ Noise
bidirectional/1024 epoll bytes_per_sec 304.7 MB/s 303.3 MB/s 🔴▼ -0.28% 0.53%
bidirectional/1024 uring bytes_per_sec 304.5 MB/s 302.0 MB/s 🔴▼ -0.62% 1.32%
bidirectional/1048576 epoll bytes_per_sec 3.19 GB/s 3.24 GB/s 🟢▲ +2.24% 1.98%
bidirectional/1048576 uring bytes_per_sec 3.34 GB/s 3.28 GB/s 🔴▼ -1.00% 2.04%
bidirectional/16384 epoll bytes_per_sec 3.13 GB/s 3.06 GB/s 🔴▼ -1.81% 1.41%
bidirectional/16384 uring bytes_per_sec 2.43 GB/s 2.43 GB/s 🔴▼ -0.38% 1.19%
bidirectional/262144 epoll bytes_per_sec 3.17 GB/s 3.18 GB/s 🟢▲ +0.98% 3.43%
bidirectional/262144 uring bytes_per_sec 3.33 GB/s 3.30 GB/s 🔴▼ -1.61% 1.85%
bidirectional/4096 epoll bytes_per_sec 1.01 GB/s 1.00 GB/s 🔴▼ -0.11% 1.12%
bidirectional/4096 uring bytes_per_sec 996.1 MB/s 995.2 MB/s 🔴▼ -0.45% 1.32%
bidirectional/65536 epoll bytes_per_sec 2.95 GB/s 2.95 GB/s 🟢▲ +0.28% 1.83%
bidirectional/65536 uring bytes_per_sec 3.04 GB/s 3.00 GB/s 🔴▼ -1.65% 3.00%
bidirectional_lockless/1024 epoll bytes_per_sec 309.1 MB/s 307.4 MB/s 🔴▼ -0.54% 1.17%
bidirectional_lockless/1024 uring bytes_per_sec 304.1 MB/s 305.7 MB/s 🔴▼ -0.07% 1.23%
bidirectional_lockless/1048576 epoll bytes_per_sec 3.21 GB/s 3.24 GB/s 🟢▲ +1.05% 1.29%
bidirectional_lockless/1048576 uring bytes_per_sec 3.42 GB/s 3.34 GB/s 🔴▼ -2.16% 2.59%
bidirectional_lockless/16384 epoll bytes_per_sec 3.12 GB/s 3.09 GB/s 🔴▼ -2.68% 1.70%
bidirectional_lockless/16384 uring bytes_per_sec 2.63 GB/s 2.64 GB/s 🔴▼ -0.55% 1.70%
bidirectional_lockless/262144 epoll bytes_per_sec 3.18 GB/s 3.19 GB/s 🟢▲ +0.15% 2.80%
bidirectional_lockless/262144 uring bytes_per_sec 3.40 GB/s 3.35 GB/s 🔴▼ -1.93% 2.52%
bidirectional_lockless/4096 epoll bytes_per_sec 1.02 GB/s 1.01 GB/s 🔴▼ -0.80% 1.27%
bidirectional_lockless/4096 uring bytes_per_sec 1000.0 MB/s 1.00 GB/s 🟢▲ +0.70% 1.08%
bidirectional_lockless/65536 epoll bytes_per_sec 2.97 GB/s 2.96 GB/s 🟢▲ +0.43% 1.70%
bidirectional_lockless/65536 uring bytes_per_sec 3.20 GB/s 3.17 GB/s 🟢▲ +1.12% 3.49%
unidirectional/1024 epoll bytes_per_sec 298.8 MB/s 297.5 MB/s 🔴▼ -0.18% 1.11%
unidirectional/1024 uring bytes_per_sec 303.4 MB/s 300.9 MB/s 🔴▼ -0.70% 0.72%
unidirectional/1048576 epoll bytes_per_sec 3.32 GB/s 3.37 GB/s 🟢▲ +1.70% 1.59%
unidirectional/1048576 uring bytes_per_sec 3.46 GB/s 3.42 GB/s 🟢▲ +1.29% 2.48%
unidirectional/16384 epoll bytes_per_sec 3.07 GB/s 3.04 GB/s 🔴▼ -2.57% 3.18%
unidirectional/16384 uring bytes_per_sec 2.68 GB/s 2.65 GB/s 🔴▼ -0.50% 1.98%
unidirectional/262144 epoll bytes_per_sec 3.29 GB/s 3.32 GB/s 🔴▼ -1.42% 3.46%
unidirectional/262144 uring bytes_per_sec 3.45 GB/s 3.44 GB/s 🟢▲ +0.28% 1.74%
unidirectional/4096 epoll bytes_per_sec 986.0 MB/s 981.6 MB/s 🔴▼ -0.71% 1.11%
unidirectional/4096 uring bytes_per_sec 996.9 MB/s 993.2 MB/s 🔴▼ -0.31% 0.99%
unidirectional/65536 epoll bytes_per_sec 3.25 GB/s 3.22 GB/s 🔴▼ -1.48% 0.81%
unidirectional/65536 uring bytes_per_sec 3.34 GB/s 3.33 GB/s 🔴▼ -0.50% 1.31%
unidirectional_lockless/1024 epoll bytes_per_sec 301.0 MB/s 300.6 MB/s 🔴▼ -0.38% 0.92%
unidirectional_lockless/1024 uring bytes_per_sec 304.6 MB/s 304.5 MB/s 🔴▼ -0.10% 0.91%
unidirectional_lockless/1048576 epoll bytes_per_sec 3.33 GB/s 3.35 GB/s 🟢▲ +0.17% 1.69%
unidirectional_lockless/1048576 uring bytes_per_sec 3.45 GB/s 3.40 GB/s 🔴▼ -1.49% 3.59%
unidirectional_lockless/16384 epoll bytes_per_sec 3.08 GB/s 3.06 GB/s 🔴▼ -0.50% 1.91%
unidirectional_lockless/16384 uring bytes_per_sec 2.66 GB/s 2.69 GB/s 🟢▲ +0.88% 1.94%
unidirectional_lockless/262144 epoll bytes_per_sec 3.30 GB/s 3.31 GB/s 🔴▼ -1.30% 3.50%
unidirectional_lockless/262144 uring bytes_per_sec 3.40 GB/s 3.45 GB/s 🟢▲ +3.10% 3.29%
unidirectional_lockless/4096 epoll bytes_per_sec 995.4 MB/s 989.3 MB/s 🔴▼ -0.48% 0.40%
unidirectional_lockless/4096 uring bytes_per_sec 1.00 GB/s 1.00 GB/s 🟢▲ +0.06% 1.28%
unidirectional_lockless/65536 epoll bytes_per_sec 3.28 GB/s 3.24 GB/s 🔴▼ -0.23% 2.84%
unidirectional_lockless/65536 uring bytes_per_sec 3.32 GB/s 3.34 GB/s 🟢▲ +1.07% 1.99%

socket_latency

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 epoll latency_mean_ns 14.74 µs 14.70 µs 🟢▲ +0.50% 1.19%
concurrent/1 uring latency_mean_ns 14.61 µs 14.48 µs 🟢▲ +0.46% 1.21%
concurrent/16 epoll latency_mean_ns 231.44 µs 233.01 µs 🟢▲ +0.04% 1.13%
concurrent/16 uring latency_mean_ns 236.28 µs 235.68 µs 🟢▲ +0.21% 0.13%
concurrent/4 epoll latency_mean_ns 57.99 µs 57.97 µs 🟢▲ +0.10% 1.07%
concurrent/4 uring latency_mean_ns 58.69 µs 58.23 µs 🟢▲ +0.40% 0.86%
concurrent_lockless/1 epoll latency_mean_ns 14.63 µs 14.67 µs 🟢▲ +0.01% 1.09%
concurrent_lockless/1 uring latency_mean_ns 14.58 µs 14.54 µs 🟢▲ +0.30% 0.17%
concurrent_lockless/16 epoll latency_mean_ns 231.20 µs 230.23 µs 🟢▲ +0.36% 1.19%
concurrent_lockless/16 uring latency_mean_ns 235.61 µs 235.14 µs 🟢▲ +0.13% 0.17%
concurrent_lockless/4 epoll latency_mean_ns 57.73 µs 57.50 µs 🟢▲ +0.36% 1.23%
concurrent_lockless/4 uring latency_mean_ns 58.53 µs 58.31 µs 🟢▲ +0.36% 0.19%
pingpong/1 epoll latency_mean_ns 14.71 µs 14.57 µs 🟢▲ +0.36% 1.35%
pingpong/1 uring latency_mean_ns 14.44 µs 14.50 µs 🟢▲ +0.16% 1.17%
pingpong/1024 epoll latency_mean_ns 15.08 µs 14.83 µs 🟢▲ +2.33% 1.44%
pingpong/1024 uring latency_mean_ns 14.86 µs 14.75 µs 🟢▲ +0.21% 1.11%
pingpong/64 epoll latency_mean_ns 14.80 µs 14.56 µs 🟢▲ +1.49% 1.30%
pingpong/64 uring latency_mean_ns 14.55 µs 14.49 µs 🟢▲ +0.16% 1.31%
pingpong_lockless/1 epoll latency_mean_ns 14.58 µs 14.42 µs 🟢▲ +1.02% 1.29%
pingpong_lockless/1 uring latency_mean_ns 14.50 µs 14.39 µs 🟢▲ +0.32% 1.21%
pingpong_lockless/1024 epoll latency_mean_ns 14.92 µs 14.84 µs 🟢▲ +0.45% 1.28%
pingpong_lockless/1024 uring latency_mean_ns 14.85 µs 14.72 µs 🟢▲ +0.42% 1.22%
pingpong_lockless/64 epoll latency_mean_ns 14.65 µs 14.50 µs 🟢▲ +0.77% 1.38%
pingpong_lockless/64 uring latency_mean_ns 14.60 µs 14.48 µs 🟢▲ +0.20% 1.29%

socket_throughput

Benchmark Backend Metric Base Head Δ Noise
bidirectional/1024 epoll bytes_per_sec 134.6 MB/s 134.1 MB/s 🔴▼ -0.06% 1.09%
bidirectional/1024 uring bytes_per_sec 140.7 MB/s 140.7 MB/s 🔴▼ -0.03% 0.26%
bidirectional/1048576 epoll bytes_per_sec 3.27 GB/s 3.28 GB/s 🟢▲ +0.81% 1.97%
bidirectional/1048576 uring bytes_per_sec 3.28 GB/s 3.26 GB/s 🔴▼ -0.62% 1.67%
bidirectional/16384 epoll bytes_per_sec 1.61 GB/s 1.61 GB/s 🟢▲ +0.16% 1.53%
bidirectional/16384 uring bytes_per_sec 1.54 GB/s 1.53 GB/s 🔴▼ -0.14% 1.91%
bidirectional/262144 epoll bytes_per_sec 3.24 GB/s 3.22 GB/s 🔴▼ -0.95% 1.04%
bidirectional/262144 uring bytes_per_sec 3.21 GB/s 3.21 GB/s 🟢▲ +0.27% 0.70%
bidirectional/4096 epoll bytes_per_sec 503.2 MB/s 505.5 MB/s 🟢▲ +0.32% 0.64%
bidirectional/4096 uring bytes_per_sec 492.7 MB/s 492.2 MB/s 🔴▼ -0.29% 0.47%
bidirectional/65536 epoll bytes_per_sec 2.55 GB/s 2.53 GB/s 🔴▼ -1.55% 2.53%
bidirectional/65536 uring bytes_per_sec 2.78 GB/s 2.77 GB/s 🔴▼ -0.37% 1.84%
bidirectional_lockless/1024 epoll bytes_per_sec 134.9 MB/s 134.6 MB/s 🟢▲ +0.29% 1.24%
bidirectional_lockless/1024 uring bytes_per_sec 141.5 MB/s 141.4 MB/s 🔴▼ -0.13% 1.00%
bidirectional_lockless/1048576 epoll bytes_per_sec 3.30 GB/s 3.26 GB/s 🔴▼ -1.83% 2.98%
bidirectional_lockless/1048576 uring bytes_per_sec 3.35 GB/s 3.36 GB/s 🟢▲ +0.05% 0.75%
bidirectional_lockless/16384 epoll bytes_per_sec 1.64 GB/s 1.63 GB/s 🟢▲ +0.13% 1.73%
bidirectional_lockless/16384 uring bytes_per_sec 1.54 GB/s 1.55 GB/s 🟢▲ +1.01% 0.99%
bidirectional_lockless/262144 epoll bytes_per_sec 3.23 GB/s 3.20 GB/s 🔴▼ -1.05% 1.04%
bidirectional_lockless/262144 uring bytes_per_sec 3.28 GB/s 3.29 GB/s 🟢▲ +0.04% 1.13%
bidirectional_lockless/4096 epoll bytes_per_sec 508.8 MB/s 508.8 MB/s 🟢▲ +0.34% 1.45%
bidirectional_lockless/4096 uring bytes_per_sec 495.3 MB/s 498.2 MB/s 🟢▲ +0.46% 1.27%
bidirectional_lockless/65536 epoll bytes_per_sec 2.53 GB/s 2.53 GB/s 🔴▼ -1.44% 1.88%
bidirectional_lockless/65536 uring bytes_per_sec 2.76 GB/s 2.80 GB/s 🟢▲ +0.25% 2.41%
multithread/2 epoll bytes_per_sec 3.41 GB/s 3.42 GB/s 🔴▼ -0.20% 0.95%
multithread/2 uring bytes_per_sec 3.63 GB/s 3.64 GB/s 🟢▲ +0.48% 0.97%
multithread/4 epoll bytes_per_sec 4.89 GB/s 4.87 GB/s 🔴▼ -0.37% 0.76%
multithread/4 uring bytes_per_sec 5.07 GB/s 5.07 GB/s 🟢▲ +0.08% 0.36%
multithread/8 epoll bytes_per_sec 4.96 GB/s 4.95 GB/s 🔴▼ -0.18% 0.38%
multithread/8 uring bytes_per_sec 5.12 GB/s 5.12 GB/s 🔴▼ -0.23% 0.33%
unidirectional/1024 epoll bytes_per_sec 126.4 MB/s 125.6 MB/s 🔴▼ -0.51% 1.17%
unidirectional/1024 uring bytes_per_sec 139.8 MB/s 139.7 MB/s 🟢▲ +0.17% 0.93%
unidirectional/1048576 epoll bytes_per_sec 3.39 GB/s 3.38 GB/s 🔴▼ -0.33% 1.23%
unidirectional/1048576 uring bytes_per_sec 3.43 GB/s 3.43 GB/s 🟢▲ +0.28% 1.22%
unidirectional/16384 epoll bytes_per_sec 1.55 GB/s 1.53 GB/s 🔴▼ -1.01% 1.68%
unidirectional/16384 uring bytes_per_sec 1.56 GB/s 1.53 GB/s 🔴▼ -1.84% 2.48%
unidirectional/262144 epoll bytes_per_sec 3.35 GB/s 3.33 GB/s 🔴▼ -0.29% 1.16%
unidirectional/262144 uring bytes_per_sec 3.22 GB/s 3.21 GB/s 🔴▼ -0.63% 1.15%
unidirectional/4096 epoll bytes_per_sec 475.8 MB/s 471.1 MB/s 🔴▼ -0.71% 0.97%
unidirectional/4096 uring bytes_per_sec 492.5 MB/s 495.3 MB/s 🟢▲ +0.59% 1.31%
unidirectional/65536 epoll bytes_per_sec 2.65 GB/s 2.63 GB/s 🔴▼ -0.91% 4.51%
unidirectional/65536 uring bytes_per_sec 2.72 GB/s 2.71 GB/s 🔴▼ -0.56% 0.54%
unidirectional_lockless/1024 epoll bytes_per_sec 127.5 MB/s 126.3 MB/s 🔴▼ -0.66% 1.44%
unidirectional_lockless/1024 uring bytes_per_sec 140.1 MB/s 140.2 MB/s 🔴▼ -0.06% 1.06%
unidirectional_lockless/1048576 epoll bytes_per_sec 3.38 GB/s 3.37 GB/s 🔴▼ -0.65% 1.81%
unidirectional_lockless/1048576 uring bytes_per_sec 3.34 GB/s 3.35 GB/s 🟢▲ +0.30% 1.09%
unidirectional_lockless/16384 epoll bytes_per_sec 1.55 GB/s 1.54 GB/s 🔴▼ -1.07% 2.18%
unidirectional_lockless/16384 uring bytes_per_sec 1.63 GB/s 1.62 GB/s 🔴▼ -0.29% 1.46%
unidirectional_lockless/262144 epoll bytes_per_sec 3.36 GB/s 3.36 GB/s 🔴▼ -0.65% 1.59%
unidirectional_lockless/262144 uring bytes_per_sec 3.25 GB/s 3.27 GB/s 🟢▲ +0.27% 1.17%
unidirectional_lockless/4096 epoll bytes_per_sec 477.6 MB/s 474.1 MB/s 🔴▼ -0.42% 1.31%
unidirectional_lockless/4096 uring bytes_per_sec 492.2 MB/s 492.5 MB/s 🟢▲ +0.07% 1.06%
unidirectional_lockless/65536 epoll bytes_per_sec 2.78 GB/s 2.70 GB/s 🔴▼ -1.55% 4.73%
unidirectional_lockless/65536 uring bytes_per_sec 2.73 GB/s 2.74 GB/s 🔴▼ -0.44% 2.00%
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.53K ops/s 🔴▼ -0.31% 0.29%
burst/100 iocp ops_per_sec 149.1 ops/s 150.1 ops/s 🟢▲ +0.96% 0.57%
burst_lockless/10 iocp ops_per_sec 1.54K ops/s 1.54K ops/s 🔴▼ -0.02% 0.40%
burst_lockless/100 iocp ops_per_sec 152.2 ops/s 153.3 ops/s 🟢▲ +0.45% 0.62%
concurrent/1 iocp ops_per_sec 12.24K ops/s 12.23K ops/s 🟢▲ +0.16% 1.32%
concurrent/16 iocp ops_per_sec 13.23K ops/s 13.23K ops/s 🟢▲ +0.24% 0.39%
concurrent/4 iocp ops_per_sec 12.94K ops/s 12.92K ops/s 🔴▼ -0.47% 0.44%
sequential iocp ops_per_sec 12.18K ops/s 12.12K ops/s 🔴▼ -1.29% 1.19%
sequential_lockless iocp ops_per_sec 12.25K ops/s 12.26K ops/s 🔴▼ -0.14% 1.22%

fan_out

Benchmark Backend Metric Base Head Δ Noise
concurrent_parents/1 iocp ops_per_sec 7.19K ops/s 7.19K ops/s 🔴▼ -0.11% 0.29%
concurrent_parents/16 iocp ops_per_sec 6.42K ops/s 6.44K ops/s 🟢▲ +0.07% 1.38%
concurrent_parents/4 iocp ops_per_sec 6.90K ops/s 6.91K ops/s 🔴▼ -0.17% 1.06%
concurrent_parents_lockless/1 iocp ops_per_sec 7.20K ops/s 7.19K ops/s 🔴▼ -0.06% 0.27%
concurrent_parents_lockless/16 iocp ops_per_sec 6.44K ops/s 6.47K ops/s 🟢▲ +0.24% 0.89%
concurrent_parents_lockless/4 iocp ops_per_sec 6.93K ops/s 6.94K ops/s 🟢▲ +0.11% 0.86%
fork_join/1 iocp ops_per_sec 114.0K ops/s 113.2K ops/s 🔴▼ -0.92% 0.28%
fork_join/16 iocp ops_per_sec 7.19K ops/s 7.17K ops/s 🔴▼ -0.34% 0.50%
fork_join/4 iocp ops_per_sec 29.41K ops/s 29.23K ops/s 🔴▼ -0.50% 0.67%
fork_join/64 iocp ops_per_sec 1.73K ops/s 1.73K ops/s 🔴▼ -0.38% 1.37%
fork_join_lockless/1 iocp ops_per_sec 113.5K ops/s 113.1K ops/s 🔴▼ -0.52% 0.43%
fork_join_lockless/16 iocp ops_per_sec 7.19K ops/s 7.18K ops/s 🔴▼ -0.11% 0.35%
fork_join_lockless/4 iocp ops_per_sec 29.34K ops/s 29.26K ops/s 🔴▼ -0.28% 0.37%
fork_join_lockless/64 iocp ops_per_sec 1.73K ops/s 1.73K ops/s 🔴▼ -0.41% 1.23%
nested/16 iocp ops_per_sec 1.70K ops/s 1.70K ops/s 🔴▼ -0.33% 1.29%
nested/4 iocp ops_per_sec 7.05K ops/s 7.04K ops/s 🔴▼ -0.08% 0.26%
nested_lockless/16 iocp ops_per_sec 1.69K ops/s 1.70K ops/s 🔴▼ -0.29% 1.14%
nested_lockless/4 iocp ops_per_sec 7.05K ops/s 7.02K ops/s 🔴▼ -0.41% 0.39%

http_server

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 iocp ops_per_sec 111.0K ops/s 111.5K ops/s 🟢▲ +0.72% 0.50%
concurrent/16 iocp ops_per_sec 107.9K ops/s 108.4K ops/s 🟢▲ +0.36% 0.19%
concurrent/32 iocp ops_per_sec 107.1K ops/s 107.9K ops/s 🟢▲ +0.68% 0.26%
concurrent/4 iocp ops_per_sec 108.9K ops/s 108.9K ops/s 🔴▼ -0.08% 0.41%
multithread/1 iocp ops_per_sec 107.2K ops/s 107.9K ops/s 🟢▲ +0.33% 0.36%
multithread/16 iocp ops_per_sec 266.7K ops/s 265.8K ops/s 🔴▼ -0.45% 0.48%
multithread/2 iocp ops_per_sec 180.5K ops/s 179.8K ops/s 🔴▼ -0.22% 0.73%
multithread/4 iocp ops_per_sec 224.9K ops/s 225.1K ops/s 🟢▲ +0.08% 0.48%
multithread/8 iocp ops_per_sec 266.7K ops/s 266.4K ops/s 🔴▼ -0.14% 0.55%
single_conn iocp ops_per_sec 111.3K ops/s 111.2K ops/s 🔴▼ -0.12% 0.56%
single_conn_lockless iocp ops_per_sec 111.2K ops/s 111.4K ops/s 🔴▼ -0.06% 0.33%

socket_latency

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 iocp latency_mean_ns 7.56 µs 7.58 µs 🔴▼ -0.22% 0.33%
concurrent/16 iocp latency_mean_ns 131.68 µs 125.28 µs 🟢▲ +4.10% 4.59%
concurrent/4 iocp latency_mean_ns 30.38 µs 30.46 µs 🔴▼ -0.20% 0.24%
concurrent_lockless/1 iocp latency_mean_ns 7.59 µs 7.56 µs 🟢▲ +0.36% 0.37%
concurrent_lockless/16 iocp latency_mean_ns 121.62 µs 121.81 µs 🟢▲ +0.17% 0.62%
concurrent_lockless/4 iocp latency_mean_ns 30.40 µs 30.43 µs 🔴▼ -0.34% 0.60%
pingpong/1 iocp latency_mean_ns 7.58 µs 7.54 µs 🟢▲ +0.48% 0.49%
pingpong/1024 iocp latency_mean_ns 7.68 µs 7.67 µs 🟢▲ +0.19% 0.51%
pingpong/64 iocp latency_mean_ns 7.60 µs 7.57 µs 🟢▲ +0.40% 0.56%
pingpong_lockless/1 iocp latency_mean_ns 7.55 µs 7.55 µs 🟢▲ +0.14% 0.37%
pingpong_lockless/1024 iocp latency_mean_ns 7.66 µs 7.67 µs 🔴▼ -0.03% 0.50%
pingpong_lockless/64 iocp latency_mean_ns 7.58 µs 7.55 µs 🟢▲ +0.18% 0.28%

socket_throughput

Benchmark Backend Metric Base Head Δ Noise
bidirectional/1024 iocp bytes_per_sec 281.3 MB/s 281.9 MB/s 🟢▲ +0.32% 0.45%
bidirectional/1048576 iocp bytes_per_sec 5.22 GB/s 5.39 GB/s 🔴▼ -0.54% 8.90%
bidirectional/16384 iocp bytes_per_sec 3.73 GB/s 3.74 GB/s 🟢▲ +0.05% 1.05%
bidirectional/262144 iocp bytes_per_sec 9.56 GB/s 9.65 GB/s 🟢▲ +0.74% 1.18%
bidirectional/4096 iocp bytes_per_sec 1.08 GB/s 1.08 GB/s 🟢▲ +0.02% 0.33%
bidirectional/65536 iocp bytes_per_sec 8.95 GB/s 9.07 GB/s 🟢▲ +1.19% 1.33%
bidirectional_lockless/1024 iocp bytes_per_sec 281.9 MB/s 282.4 MB/s 🔴▼ -0.21% 0.60%
bidirectional_lockless/1048576 iocp bytes_per_sec 5.51 GB/s 5.72 GB/s 🟢▲ +2.35% 10.38%
bidirectional_lockless/16384 iocp bytes_per_sec 3.71 GB/s 3.73 GB/s 🟢▲ +0.43% 0.49%
bidirectional_lockless/262144 iocp bytes_per_sec 9.78 GB/s 9.74 GB/s 🟢▲ +0.08% 1.73%
bidirectional_lockless/4096 iocp bytes_per_sec 1.08 GB/s 1.08 GB/s 🟢▲ +0.51% 0.54%
bidirectional_lockless/65536 iocp bytes_per_sec 8.90 GB/s 8.96 GB/s 🟢▲ +0.21% 1.07%
multithread/2 iocp bytes_per_sec 12.80 GB/s 12.71 GB/s 🔴▼ -0.67% 0.63%
multithread/4 iocp bytes_per_sec 17.05 GB/s 17.04 GB/s 🔴▼ -0.18% 0.61%
multithread/8 iocp bytes_per_sec 18.39 GB/s 18.43 GB/s 🟢▲ +0.28% 1.06%
unidirectional/1024 iocp bytes_per_sec 285.9 MB/s 285.3 MB/s 🔴▼ -0.24% 0.58%
unidirectional/1048576 iocp bytes_per_sec 4.38 GB/s 4.32 GB/s 🔴▼ -1.31% 3.53%
unidirectional/16384 iocp bytes_per_sec 3.82 GB/s 3.79 GB/s 🔴▼ -0.21% 0.60%
unidirectional/262144 iocp bytes_per_sec 8.80 GB/s 8.89 GB/s 🟢▲ +2.42% 3.53%
unidirectional/4096 iocp bytes_per_sec 1.09 GB/s 1.09 GB/s ⚪ 0.00% 0.77%
unidirectional/65536 iocp bytes_per_sec 9.32 GB/s 9.21 GB/s 🔴▼ -1.64% 1.21%
unidirectional_lockless/1024 iocp bytes_per_sec 285.5 MB/s 286.1 MB/s 🟢▲ +0.22% 0.45%
unidirectional_lockless/1048576 iocp bytes_per_sec 4.83 GB/s 4.93 GB/s 🟢▲ +1.32% 4.51%
unidirectional_lockless/16384 iocp bytes_per_sec 3.81 GB/s 3.77 GB/s 🔴▼ -0.12% 1.58%
unidirectional_lockless/262144 iocp bytes_per_sec 9.69 GB/s 9.74 GB/s 🟢▲ +1.28% 1.05%
unidirectional_lockless/4096 iocp bytes_per_sec 1.09 GB/s 1.09 GB/s 🔴▼ -0.32% 0.49%
unidirectional_lockless/65536 iocp bytes_per_sec 9.32 GB/s 9.16 GB/s 🟢▲ +0.72% 4.38%
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.23K ops/s 🔴▼ -0.79% 0.89%
burst/100 kqueue ops_per_sec 431.9 ops/s 435.6 ops/s 🟢▲ +0.63% 1.14%
burst_lockless/10 kqueue ops_per_sec 4.27K ops/s 4.25K ops/s 🔴▼ -0.36% 0.80%
burst_lockless/100 kqueue ops_per_sec 431.6 ops/s 433.1 ops/s 🟢▲ +0.60% 1.06%
concurrent/1 kqueue ops_per_sec 19.62K ops/s 19.65K ops/s 🟢▲ +0.14% 0.81%
concurrent/16 kqueue ops_per_sec 35.31K ops/s 35.11K ops/s 🔴▼ -0.25% 1.24%
concurrent/4 kqueue ops_per_sec 29.07K ops/s 29.58K ops/s 🟢▲ +1.63% 0.43%
sequential kqueue ops_per_sec 19.84K ops/s 19.97K ops/s 🟢▲ +0.58% 0.68%
sequential_lockless kqueue ops_per_sec 19.70K ops/s 19.99K ops/s 🟢▲ +2.02% 0.95%

fan_out

Benchmark Backend Metric Base Head Δ Noise
concurrent_parents/1 kqueue ops_per_sec 7.72K ops/s 8.05K ops/s 🟢▲ +4.30% 0.63%
concurrent_parents/16 kqueue ops_per_sec 7.50K ops/s 8.04K ops/s 🟢▲ +1.47% 18.05%
concurrent_parents/4 kqueue ops_per_sec 8.18K ops/s 8.20K ops/s 🟢▲ +0.75% 1.59%
concurrent_parents_lockless/1 kqueue ops_per_sec 7.78K ops/s 8.10K ops/s 🟢▲ +4.26% 0.76%
concurrent_parents_lockless/16 kqueue ops_per_sec 7.59K ops/s 8.17K ops/s 🟢▲ +1.29% 17.95%
concurrent_parents_lockless/4 kqueue ops_per_sec 8.19K ops/s 8.24K ops/s 🟢▲ +1.01% 1.81%
fork_join/1 kqueue ops_per_sec 45.94K ops/s 48.93K ops/s 🟢▲ +6.21% 0.64%
fork_join/16 kqueue ops_per_sec 7.72K ops/s 8.03K ops/s 🟢▲ +4.14% 0.63%
fork_join/4 kqueue ops_per_sec 21.70K ops/s 23.69K ops/s 🟢▲ +9.06% 0.64%
fork_join/64 kqueue ops_per_sec 2.04K ops/s 2.05K ops/s 🟢▲ +1.49% 2.22%
fork_join_lockless/1 kqueue ops_per_sec 46.84K ops/s 50.04K ops/s 🟢▲ +6.56% 0.67%
fork_join_lockless/16 kqueue ops_per_sec 7.79K ops/s 8.12K ops/s 🟢▲ +4.40% 0.90%
fork_join_lockless/4 kqueue ops_per_sec 21.87K ops/s 23.73K ops/s 🟢▲ +8.25% 0.76%
fork_join_lockless/64 kqueue ops_per_sec 2.06K ops/s 2.07K ops/s 🟢▲ +1.40% 2.44%
nested/16 kqueue ops_per_sec 2.02K ops/s 2.03K ops/s 🟢▲ +0.96% 2.23%
nested/4 kqueue ops_per_sec 7.09K ops/s 7.97K ops/s 🟢▲ +12.48% 0.48%
nested_lockless/16 kqueue ops_per_sec 2.03K ops/s 2.05K ops/s 🟢▲ +1.83% 2.29%
nested_lockless/4 kqueue ops_per_sec 7.19K ops/s 8.06K ops/s 🟢▲ +12.12% 0.78%

http_server

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 kqueue ops_per_sec 49.59K ops/s 49.20K ops/s 🔴▼ -0.84% 0.35%
concurrent/16 kqueue ops_per_sec 127.5K ops/s 130.5K ops/s 🟢▲ +2.51% 1.03%
concurrent/32 kqueue ops_per_sec 127.6K ops/s 128.6K ops/s 🟢▲ +0.49% 1.30%
concurrent/4 kqueue ops_per_sec 88.50K ops/s 89.96K ops/s 🟢▲ +1.37% 0.50%
multithread/1 kqueue ops_per_sec 127.3K ops/s 128.7K ops/s 🟢▲ +1.69% 1.28%
multithread/16 kqueue ops_per_sec 128.1K ops/s 133.7K ops/s 🟢▲ +5.01% 1.04%
multithread/2 kqueue ops_per_sec 175.7K ops/s 185.5K ops/s 🟢▲ +5.70% 1.55%
multithread/4 kqueue ops_per_sec 160.8K ops/s 162.0K ops/s 🟢▲ +0.55% 0.82%
multithread/8 kqueue ops_per_sec 131.8K ops/s 137.6K ops/s 🟢▲ +4.02% 1.25%
single_conn kqueue ops_per_sec 49.62K ops/s 49.23K ops/s 🔴▼ -0.87% 0.26%
single_conn_lockless kqueue ops_per_sec 49.82K ops/s 49.50K ops/s 🔴▼ -0.58% 0.33%

local_socket_latency

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 kqueue latency_mean_ns 2.06 µs 1.84 µs 🟢▲ +10.90% 0.31%
concurrent/16 kqueue latency_mean_ns 30.63 µs 27.19 µs 🟢▲ +11.12% 0.49%
concurrent/4 kqueue latency_mean_ns 7.68 µs 6.83 µs 🟢▲ +11.14% 0.54%
concurrent_lockless/1 kqueue latency_mean_ns 2.03 µs 1.82 µs 🟢▲ +10.21% 0.27%
concurrent_lockless/16 kqueue latency_mean_ns 30.19 µs 26.93 µs 🟢▲ +10.72% 0.31%
concurrent_lockless/4 kqueue latency_mean_ns 7.55 µs 6.78 µs 🟢▲ +10.35% 0.49%
pingpong/1 kqueue latency_mean_ns 2.05 µs 1.83 µs 🟢▲ +10.77% 0.35%
pingpong/1024 kqueue latency_mean_ns 2.16 µs 1.93 µs 🟢▲ +10.87% 0.50%
pingpong/64 kqueue latency_mean_ns 2.06 µs 1.84 µs 🟢▲ +10.50% 0.25%
pingpong_lockless/1 kqueue latency_mean_ns 2.03 µs 1.82 µs 🟢▲ +10.31% 0.38%
pingpong_lockless/1024 kqueue latency_mean_ns 2.13 µs 1.91 µs 🟢▲ +10.22% 0.69%
pingpong_lockless/64 kqueue latency_mean_ns 2.02 µs 1.82 µs 🟢▲ +10.11% 0.40%

local_socket_throughput

Benchmark Backend Metric Base Head Δ Noise
bidirectional/1024 kqueue bytes_per_sec 1.22 GB/s 1.30 GB/s 🟢▲ +6.89% 0.66%
bidirectional/1048576 kqueue bytes_per_sec 3.84 GB/s 3.83 GB/s 🔴▼ -0.21% 0.70%
bidirectional/16384 kqueue bytes_per_sec 3.83 GB/s 3.81 GB/s 🔴▼ -0.47% 0.82%
bidirectional/262144 kqueue bytes_per_sec 3.83 GB/s 3.82 GB/s 🔴▼ -0.12% 1.07%
bidirectional/4096 kqueue bytes_per_sec 2.90 GB/s 2.88 GB/s 🔴▼ -0.68% 0.54%
bidirectional/65536 kqueue bytes_per_sec 3.84 GB/s 3.82 GB/s 🔴▼ -0.76% 0.80%
bidirectional_lockless/1024 kqueue bytes_per_sec 1.23 GB/s 1.31 GB/s 🟢▲ +6.62% 0.86%
bidirectional_lockless/1048576 kqueue bytes_per_sec 3.91 GB/s 3.90 GB/s 🔴▼ -0.48% 1.13%
bidirectional_lockless/16384 kqueue bytes_per_sec 3.90 GB/s 3.90 GB/s 🔴▼ -0.17% 0.86%
bidirectional_lockless/262144 kqueue bytes_per_sec 3.91 GB/s 3.91 GB/s 🔴▼ -0.46% 1.33%
bidirectional_lockless/4096 kqueue bytes_per_sec 2.95 GB/s 2.93 GB/s 🔴▼ -0.79% 0.58%
bidirectional_lockless/65536 kqueue bytes_per_sec 3.91 GB/s 3.89 GB/s 🔴▼ -0.28% 1.02%
unidirectional/1024 kqueue bytes_per_sec 1.19 GB/s 1.28 GB/s 🟢▲ +7.45% 0.83%
unidirectional/1048576 kqueue bytes_per_sec 3.47 GB/s 3.46 GB/s 🔴▼ -0.41% 0.65%
unidirectional/16384 kqueue bytes_per_sec 3.46 GB/s 3.47 GB/s 🟢▲ +0.02% 0.50%
unidirectional/262144 kqueue bytes_per_sec 3.47 GB/s 3.45 GB/s 🔴▼ -0.70% 0.39%
unidirectional/4096 kqueue bytes_per_sec 2.68 GB/s 2.67 GB/s 🔴▼ -0.47% 0.79%
unidirectional/65536 kqueue bytes_per_sec 3.46 GB/s 3.45 GB/s 🔴▼ -0.81% 0.82%
unidirectional_lockless/1024 kqueue bytes_per_sec 1.20 GB/s 1.28 GB/s 🟢▲ +7.09% 1.25%
unidirectional_lockless/1048576 kqueue bytes_per_sec 3.52 GB/s 3.50 GB/s 🔴▼ -0.35% 0.61%
unidirectional_lockless/16384 kqueue bytes_per_sec 3.52 GB/s 3.52 GB/s 🔴▼ -0.16% 0.58%
unidirectional_lockless/262144 kqueue bytes_per_sec 3.52 GB/s 3.51 GB/s 🔴▼ -0.09% 0.58%
unidirectional_lockless/4096 kqueue bytes_per_sec 2.73 GB/s 2.70 GB/s 🔴▼ -0.86% 0.82%
unidirectional_lockless/65536 kqueue bytes_per_sec 3.52 GB/s 3.51 GB/s 🔴▼ -0.11% 0.64%

socket_latency

Benchmark Backend Metric Base Head Δ Noise
concurrent/1 kqueue latency_mean_ns 18.68 µs 18.71 µs 🔴▼ -0.15% 0.46%
concurrent/16 kqueue latency_mean_ns 120.22 µs 119.69 µs 🟢▲ +0.65% 0.82%
concurrent/4 kqueue latency_mean_ns 43.47 µs 42.56 µs 🟢▲ +2.12% 1.02%
concurrent_lockless/1 kqueue latency_mean_ns 18.60 µs 18.67 µs 🔴▼ -0.41% 0.33%
concurrent_lockless/16 kqueue latency_mean_ns 120.04 µs 119.13 µs 🟢▲ +0.85% 0.68%
concurrent_lockless/4 kqueue latency_mean_ns 42.98 µs 42.30 µs 🟢▲ +1.75% 0.59%
pingpong/1 kqueue latency_mean_ns 15.43 µs 15.41 µs 🟢▲ +0.28% 0.42%
pingpong/1024 kqueue latency_mean_ns 18.91 µs 19.02 µs 🔴▼ -0.58% 0.32%
pingpong/64 kqueue latency_mean_ns 18.70 µs 18.73 µs 🔴▼ -0.38% 0.32%
pingpong_lockless/1 kqueue latency_mean_ns 15.41 µs 15.38 µs 🟢▲ +0.17% 0.25%
pingpong_lockless/1024 kqueue latency_mean_ns 18.88 µs 19.02 µs 🔴▼ -0.70% 0.36%
pingpong_lockless/64 kqueue latency_mean_ns 18.64 µs 18.68 µs 🔴▼ -0.14% 0.38%

socket_throughput

Benchmark Backend Metric Base Head Δ Noise
bidirectional/1024 kqueue bytes_per_sec 408.2 MB/s 470.8 MB/s 🟢▲ +14.88% 0.71%
bidirectional/1048576 kqueue bytes_per_sec 7.68 GB/s 7.68 GB/s 🟢▲ +0.44% 1.00%
bidirectional/16384 kqueue bytes_per_sec 3.98 GB/s 4.51 GB/s 🟢▲ +12.66% 1.22%
bidirectional/262144 kqueue bytes_per_sec 8.78 GB/s 8.79 GB/s 🟢▲ +0.87% 0.96%
bidirectional/4096 kqueue bytes_per_sec 1.49 GB/s 1.82 GB/s 🟢▲ +22.15% 0.33%
bidirectional/65536 kqueue bytes_per_sec 7.64 GB/s 7.59 GB/s 🟢▲ +0.98% 1.98%
bidirectional_lockless/1024 kqueue bytes_per_sec 411.8 MB/s 472.7 MB/s 🟢▲ +14.19% 0.89%
bidirectional_lockless/1048576 kqueue bytes_per_sec 7.53 GB/s 7.68 GB/s 🟢▲ +0.43% 3.14%
bidirectional_lockless/16384 kqueue bytes_per_sec 4.01 GB/s 4.56 GB/s 🟢▲ +14.07% 1.21%
bidirectional_lockless/262144 kqueue bytes_per_sec 8.84 GB/s 8.77 GB/s 🔴▼ -1.00% 1.91%
bidirectional_lockless/4096 kqueue bytes_per_sec 1.51 GB/s 1.82 GB/s 🟢▲ +20.55% 1.49%
bidirectional_lockless/65536 kqueue bytes_per_sec 7.61 GB/s 7.60 GB/s 🟢▲ +0.44% 1.74%
multithread/2 kqueue bytes_per_sec 7.51 GB/s 7.48 GB/s 🔴▼ -0.93% 2.28%
multithread/4 kqueue bytes_per_sec 3.80 GB/s 3.89 GB/s 🟢▲ +1.61% 1.85%
multithread/8 kqueue bytes_per_sec 3.47 GB/s 3.51 GB/s 🟢▲ +1.84% 5.45%
unidirectional/1024 kqueue bytes_per_sec 317.5 MB/s 458.0 MB/s 🟢▲ +44.26% 0.66%
unidirectional/1048576 kqueue bytes_per_sec 8.78 GB/s 8.78 GB/s 🟢▲ +0.20% 1.35%
unidirectional/16384 kqueue bytes_per_sec 3.71 GB/s 4.42 GB/s 🟢▲ +18.99% 1.61%
unidirectional/262144 kqueue bytes_per_sec 8.90 GB/s 8.75 GB/s 🔴▼ -0.20% 2.29%
unidirectional/4096 kqueue bytes_per_sec 1.25 GB/s 1.80 GB/s 🟢▲ +44.55% 1.91%
unidirectional/65536 kqueue bytes_per_sec 7.20 GB/s 7.39 GB/s 🟢▲ +3.06% 1.76%
unidirectional_lockless/1024 kqueue bytes_per_sec 326.6 MB/s 473.7 MB/s 🟢▲ +45.23% 0.51%
unidirectional_lockless/1048576 kqueue bytes_per_sec 8.79 GB/s 8.81 GB/s 🔴▼ -0.30% 1.73%
unidirectional_lockless/16384 kqueue bytes_per_sec 3.73 GB/s 4.51 GB/s 🟢▲ +21.14% 1.59%
unidirectional_lockless/262144 kqueue bytes_per_sec 8.86 GB/s 8.92 GB/s 🟢▲ +1.11% 1.54%
unidirectional_lockless/4096 kqueue bytes_per_sec 1.25 GB/s 1.80 GB/s 🟢▲ +44.42% 0.76%
unidirectional_lockless/65536 kqueue bytes_per_sec 7.21 GB/s 7.36 GB/s 🟢▲ +1.51% 1.81%

Run & raw JSON artifacts · flag rule: |median Δ| > max(2%, 3×CV of the noisier side) · advisory only

@sgerbino sgerbino added the benchmark Triggers benchmark suite label Oct 7, 2026
@github-actions github-actions Bot removed the benchmark Triggers benchmark suite label Oct 7, 2026
@mvandeberg mvandeberg added the benchmark Triggers benchmark suite label Oct 7, 2026
@github-actions github-actions Bot removed the benchmark Triggers benchmark suite label Oct 7, 2026
@mvandeberg
mvandeberg force-pushed the pr/native-descriptors branch 2 times, most recently from bbfe808 to 1a84985 Compare October 8, 2026 17:03
Add types that adopt an open native resource into an io_context:

- posix_stream_descriptor: a stream for a pollable descriptor, such
  as a pipe, a tty, eventfd, timerfd, inotify or pidfd. It works on
  epoll, kqueue, select and io_uring.
- win_stream_handle: a stream for an overlapped Windows handle, such
  as a named pipe or a COM port.
- win_random_access_handle: positional I/O for an overlapped Windows
  handle, such as a volume.
- win_object_handle: a wait for a Windows kernel object. Processes,
  threads, events, semaphores, waitable timers and jobs are
  accepted.

assign() rejects a resource that the type cannot use. If the object
is open, assign() returns error::already_open and does not change
the object. This applies to all types that adopt a handle, and to
connect_pair().

POSIX:

- Sockets, acceptors and descriptors share one reactor base for
  register, park, cancel and close.
- The reactors set O_NONBLOCK at the first read or write. assign()
  and wait() do not change the descriptor. io_uring does not set
  O_NONBLOCK.
- wait() examines readiness with poll(). wait(read) and wait(write)
  report readiness on an error or a hangup and do not read SO_ERROR.
- kqueue watches writes only when a write must first wait.
- On macOS, kqueue uses kevent64, so a poll that must not wait
  returns at once when no event is ready.
- select watches a descriptor only while an operation waits on it.
- A descriptor that the kernel cannot poll is adopted. On epoll,
  kqueue and io_uring, an operation that must wait on it completes
  with operation_not_supported. select treats it as always ready.
- File I/O uses 64-bit offsets in 32-bit builds.
- release() on a file cancels the pending operations.

Windows:

- stream_file, random_access_file and the two overlapped handle
  types use one overlapped handle core.
- release() cancels the pending operations and removes the handle
  from the completion port. If an operation is in progress, or
  Windows refuses, release() throws and the object keeps the handle.
- The stream_file position moves by the bytes transferred. A
  completion from an earlier handle does not move it.
- win_object_handle waits through the Windows thread pool. A wait
  that the kernel satisfied always reports success.
- wait(read) and wait(write) on a socket report readiness. Only
  wait(error) reads SO_ERROR.

Add the "Native Descriptors and Handles" guide page and reference
examples for win_random_access_handle. Update the file I/O, wait,
error handling and configuration pages.

Refs cppalliance#338.
@mvandeberg
mvandeberg force-pushed the pr/native-descriptors branch from 1a84985 to c3f8715 Compare October 8, 2026 17:46
@mvandeberg mvandeberg added the benchmark Triggers benchmark suite label Oct 8, 2026
@github-actions github-actions Bot removed the benchmark Triggers benchmark suite label Oct 8, 2026
@sgerbino
sgerbino merged commit 0a387cb into cppalliance:develop Oct 9, 2026
51 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Beast2 Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants