Files
secs-gem/docs/BENCHMARKS.md
raphael dae6bfd747
tests / build-and-test (push) Successful in 2m7s
tests / thread-sanitizer (push) Successful in 2m35s
tests / tshark-dissector (push) Successful in 2m19s
tests / secs4j-interop (push) Successful in 36s
tests / libfuzzer (push) Successful in 3m8s
docs: streamline tone across reference docs
Tone pass across the non-tutorial markdown — README, PROOFS,
ARCHITECTURE, BENCHMARKS, COMPLIANCE, FAQ, MES_INTEROP, SECURITY,
and interop/README.  Three patterns came out:

- Bug-history war stories ("Past interop sweeps surfaced…",
  "What these harnesses caught: 1. Strict U-width parsing…").
- Chat-with-reader framing ("Don't skip TLS unless…", "Treat as a
  punch list", "If you're running in a pod…", "Misconfiguration
  incidents drop dramatically").
- Self-referential narration ("we ship", "our codec", "the
  codebase's most-tested layer", "three orders of magnitude above
  fab load", "the gift that keeps giving").

README also drops the standalone ThreadSanitizer subsection under
Build details (now a single line under the new Testing section).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 00:00:06 +02:00

2.7 KiB
Raw Permalink Blame History

Performance baseline

Numbers from build/secs_bench --requests 20000 --concurrency 16 on Docker / Ubuntu 24.04 inside Docker Desktop on macOS (M-series), single io_context thread. A rough capacity-planning envelope, not a lab-grade benchmark — re-run on target hardware before sizing.

Round-trip throughput / latency

Scenario Ops Elapsed Ops/sec p50 µs p95 µs p99 µs
S1F1/F2 (header-only) 20000 0.14 ~140000 74 103 161
S1F3/F4 (32 SVIDs) 20000 0.25 ~79000 165 186 260
S6F11 push (W=0) 20000 0.03 ~572000 n/a n/a n/a

A real fab tool sustains tens to a few hundred S6F11 events/second. Throughput is not the bottleneck on this stack; latency tail under contention is.

Memory footprint

A ProcessJob + ControlJob pair (no persistence enabled) is around ~450 bytes of heap (1000 pairs ≈ 0.45 MiB, measured on a fresh process). With persistence enabled add ~200 bytes of in-memory journal path tracking per record.

Active entity Approx bytes / instance
PJ + CJ pair ~450
Carrier (no slots) ~80
Carrier slot ~24
Substrate ~120
Spool entry ~40 + encoded body size

A busy fab tool tracking 50 carriers × 25 slots, 200 substrates, 20 active PJ+CJ pairs comes in well under 1 MiB of model state. RSS will be dominated by the binary itself + asio's buffers (~10-20 MiB), not the model.

How to re-run

docker compose run --rm builder /app/build/secs_bench \
    --requests 50000 \
    --concurrency 32 \
    --svid-count 32 \
    --store-pairs 10000

Output is markdown.

What this does NOT measure

  • Real network. Loopback TCP has no MTU fragmentation, no retransmits, no jitter. Production HSMS over a fab control LAN will see higher tail latency.
  • Persistence write amplification. The bench runs with persistence disabled. Each store mutation with persistence enabled is one atomic-rename to disk; on rotational media that limits you to a few hundred mutations/sec. SSD-backed deployments are fine.
  • Concurrent S6F11 enable filtering. Real CEID emission gates on the host's enable/disable list — this bench fires raw S6F11s.
  • Multi-session HSMS-GS dispatch overhead — single-session only.
  • TLS-tunneled sockets (via stunnel/sidecar) — these add ~50 µs per round-trip on modern hardware.