Skip to content

bench: pilot-bench overlay throughput benchmark harness - #445

Draft
TeoSlayer wants to merge 1 commit into
mainfrom
bench/throughput-harness
Draft

bench: pilot-bench overlay throughput benchmark harness#445
TeoSlayer wants to merge 1 commit into
mainfrom
bench/throughput-harness

Conversation

@TeoSlayer

Copy link
Copy Markdown
Collaborator

What

Repeatable throughput benchmark for the overlay, built to gate the upcoming transport-efficiency work: record a baseline once, then run + compare after each change to see per-node and fleet-median deltas.

./bench/pilot-bench.py run --label baseline    # once
./bench/pilot-bench.py run --label after-fix   # after each change
./bench/pilot-bench.py compare                 # delta table vs baseline

Per node it captures ping RTT, round-trip echo goodput + completion % (pilotctl bench --json), and live transport counters (cwnd min/max, fast_retx, srtt) sampled from pilotctl info --json during the transfer — so a slow run also records why it was slow. Results are timestamped JSON under ~/.pilot/bench-results/. Python stdlib only.

Baseline (2026-08-02, laptop → fleet, 1 MB echo, 2 trials/node)

node goodput (trials) completion cwnd range note
coingecko-markets-simple 0.204 / 0.005 MB/s 100% / 78% 30–66 KB / 4–481 KB trial 2 hit window-overshoot collapse
list-agents 0.155 / 0.206 MB/s 100% / 100% 33–62 KB / 41–525 KB
mediawiki-random 0.058 / 0.004 MB/s 100% / 55% 41–525 KB / 43–229 KB
pilot-mom 0.000 MB/s ×2 0% echo loop exits on transient ErrSendBufFull (services.go)
github-public unreachable flapping (half-open wedge)

Fleet median 0.068 MB/s · best 0.206 MB/s. The bimodal pattern confirms the diagnosis: trials where cwnd stays ≤ ~64 KB complete at ~0.2 MB/s (the window/RTT limit at 214 ms SRTT); trials where slow start overshoots to ~500 KB blow past MaxOOOBuf (128 segs) and collapse into the 1-per-RTO recovery crawl. Theoretical ceiling with a safe 512 KB window: ~2.4 MB/s (~10×).

Fix list these numbers gate

  1. Clamp MaxCongWin ≤ MaxOOOBuf×MSS (or raise MaxOOOBuf ≥ 256) — stop loss amplification
  2. SACK-driven bulk retransmit instead of 1-per-RTO; allow partial-ACK retransmit in timeout recovery
  3. Pace / HyStart-exit slow start to stop the overshoot burst
  4. Echo service: retry on ErrSendBufFull like connAdapter.Write does (v1.9.1 precedent)

🤖 Generated with Claude Code

Repeatable overlay throughput measurement to gate the transport-efficiency
work: 'run --label baseline' records reference numbers, 'run' + 'compare'
diff any later run against them, per node and fleet-median.

Per node it captures ping RTT, round-trip echo goodput and completion %
(pilotctl bench --json), and live transport counters (cwnd min/max,
fast_retx, srtt) sampled from pilotctl info --json during the transfer,
so a slow run also records why it was slow. Results are timestamped JSON
under ~/.pilot/bench-results, stdlib-only Python.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TeoSlayer pushed a commit that referenced this pull request Aug 2, 2026
…ery crawl)

Fleet benchmarks showed ~0.2 MB/s best-case round-trip goodput with
multi-minute stalls on 1 MB echo transfers (fleet median 0.068 MB/s,
PR #445 baseline). Live conn-stats sampling traced it to four compounding
defects, fixed here:

1. Loss amplification: MaxOOOBuf (128 segs) < MaxCongWin (256 segs), so
   one lost segment with a full window in flight made the receiver
   silently drop every later in-window segment. MaxOOOBuf is now 512
   (= RecvBufSize, covers the whole 2 MB receive window).

2. Recovery crawl: timeout-based recovery had no partial-ACK retransmit
   path (RFC 6582 step 6a only ran in fast recovery), leaving multi-
   segment losses to the one-per-RTO timer with RTO backed off to 10 s
   (~1.3 KB/s observed). Partial ACKs in timeout recovery now retransmit
   ACK-clocked out of slow start, and both recovery modes use the new
   retransmitLost: up to a cwnd of un-SACKed segments below the SACK
   frontier per ACK event, capped at maxRetxBurst=32. A 180-segment hole
   now drains in ~15 RTTs (~3 s) instead of up to 30 min.

3. Slow-start overshoot: initial SSThresh of MaxCongWin/2 (512 KB) let
   slow start double straight into a path-collapsing ~550 KB burst.
   InitialSSThresh is now 128 KB; congestion avoidance probes beyond it.

4. Echo service died silently on backpressure: handleEchoConn treated
   ErrSendBufFull (routine when data arrives faster than cwnd drains) as
   fatal, so bulk echoes returned 0 bytes while inbound kept ACKing
   (observed against pilot-mom). Echo now writes through connAdapter,
   which blocks-and-retries per its v1.9.1 semantics.

All changes are endpoint-local heuristics — no wire format change, safe
in a mixed-version fleet. pkg/daemon suite green incl. all RFC congestion
tests; in-repo CC simulation improves 20-35% at 0-1% loss; new zz tests
pin each fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants