Reproduce performance suites against a binary
Replay published suite kinds without a Rust toolchain for the system under test. You need a Conduit binary, Python 3 harness dependencies, and Docker for the default dnsperf path (native dnsperf is optional).
Prerequisites
- Obtain a Conduit binary (release asset, package, or a binary you already built).
- Clone or unpack a checkout that includes the
perf/tree. -
Install harness Python dependencies:
pip install -r perf/requirements.txt -
Docker available for the pinned dnsperf image (default). Build once if needed:
docker build -t dnsconduit-dnsperf:2.14.0 \ -f perf/fixtures/dnsperf/Dockerfile \ perf/fixtures/dnsperf
List and run
cd /path/to/DNSConduit
python3 -m perf.runner list --suite scale
python3 -m perf.runner list --curated
python3 -m perf.runner run \
--conduit /path/to/conduit \
--suite scale \
--profile-id local \
--render plain
Select by suite and/or scenario id (--suite and --scenario are repeatable).
You can also select by study (expands to member scenarios) or publish-set
(union of members from studies marked published):
python3 -m perf.runner list --studies -v
python3 -m perf.runner list --study sync-vs-split-io
python3 -m perf.runner run \
--conduit /path/to/conduit \
--study metrics-scrape-ladder \
--profile-id local \
--time 5 \
--render plain
# Lab refresh for curated studies (omit --time for publish-quality duration):
python3 -m perf.runner run \
--conduit /path/to/conduit \
--publish-set \
--profile-id maintainer-ws-1 \
-o perf/results/runs/publish-set-lab.json
--time 5 (or similar) is fine for smoke development. Promoted reference
JSON for published studies SHOULD share a consistent publish-quality window
on the single reference host (maintainer-ws-1) — do not mix smoke cells into
published same-host comparisons without re-running the publish-set at that quality.
Loadgen concurrency defaults match published methodology (--clients 4,
--dnsperf-threads 2, no --max-outstanding → dnsperf default ≈ 100). For
elevated probes:
python3 -m perf.runner run \
--conduit /path/to/conduit \
--scenario scale-split-io-forward-fast \
--clients 16 \
--dnsperf-threads 8 \
--max-outstanding 2000 \
--profile-id maintainer-ws-1 \
--render plain
Pass --loadgen-mode native when dnsperf is on $PATH and you prefer not to use Docker.
Decision-shaped comparisons for operators live under Tuning evidence (studies).
Re-render without re-running
python3 -m perf.runner render \
--from perf/results/runs/run-….json \
--format rich
Formats: plain, rich, yaml, json, html.
Annotations (harness footnotes)
Stable footnotes live under perf/catalog/annotations/ (YAML catalog). Attach them
at run or scenario level when recording a promote; make perf-docs renders each
id as an include fragment under operator-docs/docs/performance/includes/ and
injects marked pages (for example methodology / reference load-shape notes).
python3 -m perf.runner annotations -v
python3 -m perf.runner run \
--conduit /path/to/conduit \
--scenario scale-sync-forward-fast \
--annotation-id ann-example-context
Maintainer publish
Operator-facing interpretation (load shapes, elevated vs thin recipes, median-of-3, answer gate, CPU governor requirement) stays on Methodology. This section is the publish pipeline for refreshing committed reference JSON and regenerating docs.
Promote vs docs render
| Layer | Who | What |
|---|---|---|
| Measure + promote | Maintainer, on the single reference host | Run suites; land validated JSON under perf/results/references/ via pull request |
| Docs representation | Docs / CI generate step | From committed JSON only: regenerate tables, static SVG, CSV — no live Conduit or dnsperf |
Stale references are fixed by a maintainer lab refresh and PR, not by an automated bench on the release tag.
Lab refresh (--publish-set)
On maintainer-ws-1, set CPU governors to performance when the host offers that
governor (via cpupower, powerprofilesctl, or sysfs — see perf/README.md, Host
CPU power state). Pass --allow-suboptimal-cpu-power only for an intentional noisy
probe; that override is not publish-quality.
Raise UDP socket memory so fixture listeners.rcvbuf (4 MiB) is not clamped by
net.core.rmem_max (see perf/README.md, Host UDP receive buffers):
sudo sysctl -w net.core.rmem_max=16777216 net.core.rmem_default=4194304
The harness refuses elevated runs when rmem_max is below 4 MiB unless you pass
--allow-suboptimal-udp-buffers (expect Queries lost from kernel RcvbufErrors).
Omit short --time overrides for publish-quality duration. Curated publish uses
median of 3 independent rounds (not a single draw); see
Methodology. Example:
# N=3 publish-set → merge-median → ok-only JSON (then promote)
make perf-run-publish-set-median CONDUIT=/path/to/conduit \
PERF_PROFILE_ID=maintainer-ws-1 \
PERF_ROUNDS=3 \
PERF_MEDIAN_DIR=perf/results/runs/publish-set-median
make perf-promote \
PERF_FROM=perf/results/runs/publish-set-median/median-promotable.json \
PERF_PROFILE_ID=maintainer-ws-1 \
PERF_PROMOTE_MODE=publish-set
If one ranking cell's per-round range in quality.notes is large (roughly
≳20–25% of the median), remeasure that subset at PERF_ROUNDS=5 rather than
raising the default bag-wide N. Promote the validated median into
perf/results/references/, then regenerate operator docs (make perf-docs).
Annotation catalog wiring is in
Annotations above.
Make targets
From a checkout: make perf-list, make perf-run-scale CONDUIT=/path/to/conduit,
make perf-run-publish-set-median, make perf-render PERF_FROM=… (optional
PERF_FORMAT=plain|rich|yaml|json|html; FORMAT= is an alias).
make performance remains the microbench path and is distinct from these load
suites.
What you do not need
rustc/cargoto replay suites against a prebuilt binary- The OTLP lab receiver for scrape-only metrics scenarios (required only for OTLP
feature_taxcells; release packages includeconduit-otlp-metrics-tracerwhen companions are shipped)
See also Methodology and the in-tree perf/README.md.