TrigGuard
TRIGGUARD BENCHMARKS

Benchmarks

Measured performance. Reproducible in harness.

Headline figures match published JSON artifacts (run 2026-04-18, engine commit 979d622). Reference measurements use a single-machine localhost loopback; production adds TLS, WAN, and autoscaler effects.

Kernel FSM p99

0.018 ms

In-process · 100k iter

Swift /decide p99

0.474 ms

HTTP · 20k iter

Pipeline p99

1.28 ms

Sequential /v1/evaluate

k6 sustained RPS

~4,200

Single Node instance

Layered latency snapshot

Apple M4 Pro · macOS 15.4.1 · localhost loopback. Third-party stacks are not measured on this rig; for conceptual comparisons see policy engines.

Layerp50p95p99ThroughputSource artifact
TrigGuard kernel FSM (in-process)0.011 ms0.013 ms0.018 ms85,343/skernel_fsm_latency.json
TrigGuard Swift /decide (direct HTTP)0.168 ms0.260 ms0.474 ms5,285/sdecision_core_http_latency.json
TrigGuard /v1/evaluate pipeline (sequential)0.485 ms0.786 ms1.279 ms1,868/seval_pipeline_latency.json
TrigGuard k6 (10 VUs, 30 s)2.26 ms3.60 ms4.59 ms4,024/sk6_summary_10vu_30s.json

Methodology

How these runs are produced and verified.

Client-side percentiles

Percentiles from raw client samples. Server integer-ms fields are not used for headline reporting.

High-resolution clocks

Node process.hrtime.bigint() and Python perf_counter for wall-clock latency.

Deterministic workload

Representative spend frame; tier-1 irreversible surface with two signals for pipeline tests.

Concurrent saturation

k6 at 10 / 50 / 100 VUs against the same local stack to expose tail under load.

Open artifacts

JSON summaries and harness scripts ship in-repo for independent verification.

Throughput and tail latency under k6

What changes under load

  • Single-instance Node evaluator approaches ~4.2k RPS before queuing dominates.
  • Client p50 rises with VUs (2.26 ms to 22.71 ms) while RPS stays near saturation.
  • Error rate remained 0% across 10 / 50 / 100 VU runs.

k6 client p50 latency vs virtual users

Line chart: k6 p50 latency in milliseconds at 10, 50, and 100 virtual users ms (p50) 0 12 24 10 VU 50 VU 100 VU

From k6 summaries: p50 2.26 ms (10 VU), 11.65 ms (50 VU), 22.71 ms (100 VU). Vertical axis scaled to 24 ms.

k6 snapshot

Peak RPS (100 VU run)
4,261 / s
Total requests (50 VU / 60 s)
249,407
Errors (10 / 50 / 100 VU)
0.00%

Need your own numbers?

Run the published harness on your hardware, or work with us on a bounded evaluation plan that matches your deployment shape.

Want to run your own benchmark? Contact the team for a custom harness configuration.

Full results, reconciliation, and artifacts

Complete tables, claim reconciliation, reproduction commands, and raw JSON paths from the engineering report.

Run date: 2026-04-18 · Engine commit: 979d622 (TrigGuard/main)

Environment: Apple M4 Pro · 24 GB RAM · arm64 · macOS 15.4.1 (Darwin 24.4.0)

Runtimes: Swift 6.3 · Node 22.22 · Python 3.14 · k6 (latest)

Network: Single-host localhost loopback. Zero WAN. No Cloud Run. No TLS.

Note: Production differs with TLS termination, WAN latency, and Cloud Run cold starts.

Workload: POST /v1/evaluate with representative spend frame (tier-1 irreversible surface, two signals).

Iterations: 100,000 (kernel) · 20,000 (decision core HTTP) · 5,000 (sequential pipeline) · sustained k6 at 10 / 50 / 100 VU. Warmup: 1,000-5,000 iterations discarded per harness.

Methodology: Percentiles from raw client-side samples. Index: benchmark_summary.json.

Kernel FSM, in-process decision (no HTTP, no crypto)

trigguard.sdk.gate.check() · trigguard-system/trigguard-kernel

VariantIterationsp50p95p99p99.9maxThroughput
Default request 100,000 0.011 ms 0.013 ms 0.018 ms 0.049 ms 0.214 ms 85,343 / s
Tier-1 irreversible + 2 signals (spend) 100,000 0.007 ms 0.008 ms 0.011 ms 0.038 ms 0.141 ms 139,716 / s

Single-threaded, after 1,000-iteration warmup. The DecisionEngine path is exercised (telemetry confirms 101,000 / 101,000 gates evaluated).

Decision core over HTTP (Swift canonical core)

POST /decide · TrigGuard/remote-eval-core

VariantIterationsp50p95p99p99.9maxThroughput
Client wall-clock (hrtime) 20,000 0.168 ms 0.260 ms 0.474 ms 1.328 ms 8.710 ms 5,285 / s

Isolates the Swift FSM + HTTP framing; no Node evaluator in the hot path.

End-to-end evaluator pipeline

POST /v1/evaluate · Node evaluator → Swift canonical core → signed receipt

ScenarioIterationsp50p95p99p99.9maxThroughput
Sequential (1 client, no concurrency) 5,000 0.485 ms 0.786 ms 1.279 ms 1.973 ms 3.460 ms 1,868 / s

Full production path: canonicalization, idempotency, auth check, protocol fingerprint, receipt hashing.

Concurrent load test (k6)

VU-based sustained concurrency · error rate = 0%

Virtual usersDurationTotal requestsRPSp50p95p99p99.9Errors
10 VUs 30 s 120,734 4,024 / s 2.26 ms 3.60 ms 4.59 ms 13.63 ms 0.00%
50 VUs 60 s 249,407 4,156 / s 11.65 ms 14.78 ms 21.33 ms 28.77 ms 0.00%
100 VUs 30 s 127,889 4,261 / s 22.71 ms 28.63 ms 35.12 ms 42.46 ms 0.00%

Single-instance Node evaluator + Swift core on one machine; saturation around ~4,200 RPS. Production deployment uses horizontal autoscaling to keep per-instance concurrency well below saturation.

Site-claim reconciliation

How measured reality compares with the published headline numbers

Claim
Kernel hot path p99 < 5 ms
Kernel FSM in-process p99 = 0.018 ms
Kernel FSM signals-heavy p99 = 0.011 ms
Decision core over HTTP p99 = 0.474 ms
Supported · ~10-280× headroom
Claim
End-to-end evaluation p99 < 15 ms
Sequential pipeline p99 = 1.28 ms
10 VU concurrent p99 = 4.59 ms
50 VU concurrent p99 = 21.33 ms (per-instance saturation)
Supported at production concurrency
Scope. These runs are on a single workstation with localhost loopback; they isolate stack-internal latency from Cloud Run, TLS, and WAN hops. Production numbers for the public Cloud Run decision path are additionally bounded by ingress routing and instance cold starts; those budgets are governed separately under the SLA.

Reproduce these runs

Every number on this page comes from a committed artifact; no hand-edited values.

The full harness lives in the TrigGuard repository. After cloning, on any machine with Node 20+, Python 3.11+, Swift 5.9+ and k6 installed:

# 1. In-process kernel FSM
cd trigguard-system/trigguard-kernel
PYTHONPATH=. python3 ../../TrigGuard/scripts/bench/kernel_latency_bench.py \
 --count 100000 --warmup 1000 \
 --output ../../TrigGuard/evidence/artifacts/benchmarks/kernel_fsm_latency.json

# 2. Start Swift canonical decision core
cd ../../TrigGuard
TG_DECIDE_PORT=9090 ./scripts/start_canonical_core.sh &

# 3. Measure /decide directly
BASE_URL=http://127.0.0.1:9090 ITERATIONS=20000 WARMUP=1000 \
 OUTPUT=evidence/artifacts/benchmarks/decision_core_http_latency.json \
 node scripts/bench/pipeline_latency_bench.js # (endpoint switched to /decide)

# 4. Start Node evaluator stub with canonical core URL wired in
# Test-only flag: disables token authentication for localhost-only benchmark runs.
# Has no effect in deployed environments.
# Ignored in production configuration.
cd remote-eval-stub && NODE_ENV=test \
 TRIGGUARD_UNSAFE_LOCAL_AUTH_BYPASS=true PORT=8080 \
 TG_CANONICAL_CORE_URL=http://127.0.0.1:9090/decide \
 BULKHEAD_TENANT_MAX_IN_FLIGHT=2000 BULKHEAD_GLOBAL_MAX_IN_FLIGHT=5000 \
 RATE_LIMIT_PER_TENANT=10000000 RATE_LIMIT_GLOBAL=50000000 \
 node server.js &

# 5. End-to-end sequential pipeline
cd .. && BASE_URL=http://127.0.0.1:8080 TOKEN=test-token \
 ITERATIONS=5000 WARMUP=500 \
 OUTPUT=evidence/artifacts/benchmarks/eval_pipeline_latency.json \
 node scripts/bench/pipeline_latency_bench.js

# 6. Concurrent k6 load test
k6 run --env BASE_URL=http://127.0.0.1:8080 --env VUS=50 --env DURATION=60s \
 --env TOKEN=test-token \
 --summary-export evidence/artifacts/benchmarks/k6_summary_50vu_60s.json \
 load-tests/evaluate_bench.js

# 7. Aggregate
node scripts/aggregate_benchmarks.js

Raw artifacts

Documentation