This document defines the reproducible performance harness used for Phase 5.
- CPU governor:
performance - Target host class: dedicated self-hosted perf runner
- Kernel: captured in CI artifact metadata (
uname -r) - Filesystem target:
/etc/hostsfor open/read microbenches - Network target: loopback (
127.0.0.1) with UDPconnect()for connect microbench - Agent mode:
--auditfor overhead measurement (no deny action side effects) - Policy state: deny maps cleared (no deny rules). In audit-only mode with an empty deny policy, the daemon intentionally skips attaching file/network LSM hooks to measure idle overhead rather than enforcement cost.
- Open benchmark default iterations:
200000 - Connect benchmark default iterations:
50000 - Open regression compare uses median of repeated runs (
REPEATS=3default) - Perf gate compares baseline vs with-agent on the same host and run
- Hosted
benchmark.ymlis advisory only; strict gating runs in.github/workflows/perf.ymlon deterministic runners - Hosted benchmark runs pin execution to one CPU (
taskset -c 0) when available - Hosted benchmark comparison filters out unstable rows:
- only
meanaggregates are kept - rows below
50nsare excluded from alerting - only high-signal families listed in
config/benchmark_focus_patterns.txtare compared
- only
- Hosted benchmark alert threshold is intentionally looser (
20%) than strict perf SLO gating to account for shared-runner variance on shared runners - PR benchmark comments are disabled to prevent noisy review threads; strict
pass/fail performance evidence is reported by
.github/workflows/perf.yml - Use stable thresholds in
scripts/perf_workload_suite.sh - Strict KPI gate:
p95_with_agent / p95_baseline <= 1.05for both open and connect profiles (validated byscripts/validate_perf_artifacts.py) - Canonical SLO gate table is generated by
scripts/perf_slo_check.shand stored asperf-slo-report.md+perf-slo-summary.json
Treat Benchmark workflow alerts as early signals, not release blockers:
- If hosted alert is present but
perf.ymlpasses on self-hosted perf runners, treat the result as noise or non-critical drift. - If both hosted alert and
perf.ymlgate fail, treat it as a real regression and require mitigation before promotion.
ITERATIONS=200000 FILE=/etc/hosts scripts/perf_open_bench.sh
WITH_AGENT=1 BIN=./build/aegisbpf ITERATIONS=200000 FILE=/etc/hosts scripts/perf_open_bench.shOutput includes:
us_per_opp50_usp95_usp99_us
ITERATIONS=50000 scripts/perf_connect_bench.sh
WITH_AGENT=1 BIN=./build/aegisbpf ITERATIONS=50000 scripts/perf_connect_bench.shThe connect microbench uses UDP sockets to isolate syscall overhead and avoid accept-thread scheduling noise from TCP listener setups.
Output includes:
us_per_opp50_usp95_usp99_us
sudo BIN=./build/aegisbpf \
FILE=/etc/hosts \
OPEN_ITERATIONS=200000 \
CONNECT_ITERATIONS=50000 \
READ_ITERATIONS=50000 \
STAT_SAMPLE=400 \
STAT_ITERATIONS=50 \
MAX_OPEN_PCT=15 \
MAX_CONNECT_PCT=15 \
MAX_READ_PCT=15 \
MAX_STAT_PCT=15 \
scripts/perf_workload_suite.shThe suite fails if any workload exceeds threshold. The strict open_close <= 10%
gate remains enforced by scripts/perf_compare.sh in .github/workflows/perf.yml.
- Soak reliability and drop-ratio evidence are collected via:
scripts/soak_reliability.sh.github/workflows/soak.yml
- Product reliability target remains
<0.1%event-drop ratio under sustained benchmarked load (see CI perf artifacts).
Both open and connect benches support FORMAT=json and OUT=/path:
FORMAT=json OUT=/tmp/open.json ITERATIONS=200000 FILE=/etc/hosts scripts/perf_open_bench.sh
FORMAT=json OUT=/tmp/connect.json ITERATIONS=50000 scripts/perf_connect_bench.shCI stores these JSON profiles as perf-profiles artifacts in
.github/workflows/perf.yml.
Perf CI validates artifact schema before upload:
python3 scripts/validate_perf_artifacts.py \
--open-baseline artifacts/perf/open_baseline.json \
--open-with-agent artifacts/perf/open_with_agent.json \
--connect-baseline artifacts/perf/connect_baseline.json \
--connect-with-agent artifacts/perf/connect_with_agent.json \
--workload artifacts/perf/workload_suite.json \
--report artifacts/perf/perf-evidence-report.mdValidation guarantees:
- required JSON keys exist for each profile
- percentile ordering is sane (
p50 <= p95 <= p99) - workload suite includes all required rows
(
open_close,connect_loopback,full_read,stat_walk) - with-agent profiles are labeled consistently
- KPI ratios stay within gates:
open_p95_ratio <= 1.05connect_p95_ratio <= 1.05
Use the deterministic SLO gate script to produce one canonical table:
OPEN_JSON=artifacts/perf/open_compare.json \
WORKLOAD_JSON=artifacts/perf/workload_suite.json \
OPEN_BASELINE_JSON=artifacts/perf/open_baseline.json \
OPEN_WITH_AGENT_JSON=artifacts/perf/open_with_agent.json \
CONNECT_BASELINE_JSON=artifacts/perf/connect_baseline.json \
CONNECT_WITH_AGENT_JSON=artifacts/perf/connect_with_agent.json \
REPORT_OUT=artifacts/perf/perf-slo-report.md \
SUMMARY_OUT=artifacts/perf/perf-slo-summary.json \
scripts/perf_slo_check.shThe table rows are scenario-based (audit_mode_open, audit_mode_connect,
workload rows, optional soak rows) and each row carries a concrete budget and
pass/fail status.
Required artifacts for each strict perf run:
open_compare.jsonopen_baseline.jsonopen_with_agent.jsonconnect_baseline.jsonconnect_with_agent.jsonworkload_suite.jsonperf-slo-report.mdperf-slo-summary.jsonperf-evidence-report.mdkernel.txtos-release.txtcpu.txtfs.txt