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
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