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

66 lines
2.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```sh
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.