async: 16,000 connections at 5ms, down from 64,000 at 15ms - #1342
Conversation
Experiment. At 64,000 connections the profile has been reporting a gap between entries that does not survive inspection: instrumenting the wait shows the timer completing 3.2ms late against 23ms of end-to-end overhead, so the delay is about 13% of what is being measured and the rest is the read and write path. Fewer connections and a shorter wait puts the load somewhere different, and whether the ordering between entries holds is the thing worth knowing. The ceiling is connections over delay, so this moves it from 4.27M to 3.20M. The best entry so far is 2.24M, which leaves headroom but less than before; the docs now say so rather than claiming the ceiling does not bind. Existing results are all at async-64000 and are orphaned by this, so the column is empty until the profile is re-run. That is accepted for now. Generator runs clean and badge parity holds at 579 ranks.
The async column drops out until the profile is re-run, since every existing result is at async-64000.
|
/benchmark-multiple -f ioxide,tokio -t async Profile is now 16,000 connections at 5ms (ceiling 3.20M, down from 4.27M). Comparing the two entries under the new load. At 64,000/15ms it was ioxide 1,568,519 @ 2802% against tokio 2,263,962 @ 3970% - near-identical efficiency per unit CPU, with ioxide simply not using the box. If the gap closes here, it was connection scaling; if it holds, it is throughput. Not saving, still experimenting. |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFrameworks: 2 | Test: ✅
|
| Test | Conn | RPS | CPU | Mem | Δ RPS | Δ Mem |
|---|---|---|---|---|---|---|
| async | 16000 | 1,842,424 | 3434.9% | 822MiB | NEW | NEW |
✅ tokio
| Test | Conn | RPS | CPU | Mem | Δ RPS | Δ Mem |
|---|---|---|---|---|---|---|
| async | 16000 | 2,054,680 | 3319.6% | 672MiB | NEW | NEW |
Experiment on the experiment branch; #1341 stays on the tick. The ring was measured once, at 64,000 connections and 15ms, where it bought 5% throughput for 51% more CPU and lost. The profile has changed underneath that result: 16,000 connections at 5ms is a third of the connections and three times the request rate, and the two mechanisms scale with different things. The ring costs a timerfd_settime syscall plus an SQE and a CQE per request, so its cost tracks the request rate and this profile raises that. The tick costs one post per reactor per tick regardless of the rate, so its cost is unchanged at 64 reactors while it now amortises over fewer connections per reactor: 250 here against 1,000 before, which is 250 timers per drain becoming about 60. Both effects point the same way, against the ring, so this is a check rather than a hope. /delay/5 answers in 5.22-5.28ms on this path.
|
/benchmark-multiple -f ioxide,tokio -t async Same profile, ioxide now on the ring timer ( Tick baseline just measured on this profile: ioxide 1,842,424 @ 3434.9%, tokio 2,054,680 @ 3319.6%. At 64k/15ms the ring lost, 5% more throughput for 51% more CPU. Worth re-reading here because the profile changed underneath that result: 3x the request rate makes the ring's per-request syscall cost worse, while a quarter of the connections per reactor makes the tick's batching worse. Both point against the ring, so this is a check rather than a hope. Not saving. |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFrameworks: 2 | Test: ✅
|
| Test | Conn | RPS | CPU | Mem | Δ RPS | Δ Mem |
|---|---|---|---|---|---|---|
| async | 16000 | 2,462,698 | 5831.1% | 1.1GiB | NEW | NEW |
✅ tokio
| Test | Conn | RPS | CPU | Mem | Δ RPS | Δ Mem |
|---|---|---|---|---|---|---|
| async | 16000 | 2,055,694 | 3346.0% | 673MiB | NEW | NEW |
|
Folded into #1341 — everything is in one PR now. The two profile commits (`b3b554a4`, `ff6570b2`) were cherry-picked across. The third commit here, the ring-timer flip, was dropped as redundant: #1341 already defaults to the ring on its own measurement, and it now also carries the deadline guard that this branch was missing. |
Experiment, stacked on #1341 so the diff is only the profile change.
At 64,000 connections the profile turned out to be measuring mostly the read/write path rather than the wait: instrumenting the timer against its own deadline showed it completing 3.2ms late against 23ms of end-to-end overhead, so the delay is roughly 13% of what the number reflects.
This moves the load: 16,000 connections, 5ms wait. Ceiling goes 4.27M -> 3.20M (connections over delay), against a best-so-far of 2.24M, so there is headroom but less than before and the docs now say so instead of claiming the ceiling does not bind.
Touches
profiles.sh, the gcannon raw template, the CATALOG row, both profile docs and the README table. Generator runs clean, badge parity holds at 579 ranks.Existing
async-64000results are orphaned and the column is empty until a re-run. Accepted while experimenting.