# RQ3 Microbenchmark Results
Per-aspect overhead and 4-aspect composition cost at the tool-dispatch
join point. Reproduce with:
```
cargo bench -p aspect-std --bench agentic_aspects
```
## Environment
| Date | 2026-05-12 |
| CPU | Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz |
| Kernel | Linux 5.15.0-173-generic x86_64 |
| Toolchain | rustc 1.96.0-nightly (38c0de8dc 2026-02-28) |
| Profile | `release` (criterion default) |
| Iterations | criterion defaults: 3 s warm-up, 5 s measurement, 100 samples |
| Commit | record at run time with `git rev-parse HEAD` |
## Results
Times are mean over 100 samples. 95% CIs from criterion's bootstrap.
### Baseline
| `dispatch_body` (raw target) | 4.1 ns | [4.1, 4.1] |
| `empty_chain` (harness only) | 29.9 ns | [29.9, 29.9] |
Harness floor: ~26 ns on top of a 4 ns target call.
### Single aspect at the tool-dispatch join point
| `RateLimiter` | 394 ns | [394, 394] |
| `TokenBudget` | 554 ns | [554, 554] |
| `StructuredLogger` | 640 ns | [640, 641] |
| `ToolScopeSandbox` | 753 ns | [751, 754] |
| `ActionAuditTrail` | 1,292 ns | [744, 2,382] |
`ActionAuditTrail` has a wide CI because the bench appends to an
unbounded `Vec<AuditRecord>` across all iterations; allocator
behaviour dominates the tail. A production deployment would rotate
the trail (e.g. flush to disk every N records), which we measure
separately in the chain benches below.
### Composition (firing order: Sandbox → RateLimiter → [TokenBudget] → AuditTrail → Logger)
| 2 | Sandbox, RateLimiter | 1,086 ns | [1,086, 1,086] |
| 3 | + AuditTrail | 2,964 ns | [1,907, 5,074] |
| 4 | + Logger | 4,126 ns | [2,783, 6,799] |
| 5 | + TokenBudget (full set) | 4,916 ns | [3,491, 7,746] |
Chain depths ≥ 3 inherit the audit-trail allocator variance noted above.
### Short-circuit floor
| Sandbox denies, 4-chain declared | 1,464 ns | [1,464, 1,465] |
Sandbox runs, returns `Err`, inner three aspects never fire. This is
the floor cost of a security denial through the full chain.
## Interpretation
- Full 5-aspect chain: **~4.9 µs** per tool dispatch — three orders of
magnitude below typical LLM tool-call latency (1–100 ms), so the
framework is not the bottleneck on the agent hot path.
- Per-aspect marginal cost: roughly 700–1,300 ns added per layer,
depending on what the aspect does. `Box<dyn Aspect>` virtual
dispatch + `Arc` cloning at each layer is the floor.
- Short-circuit path is **3.4× faster** than the full pass (1.5 µs
vs. 4.9 µs at depth 5), confirming that outermost-first ordering
for security aspects pays off when denials are common.
## Caveats
- Audit-trail bench grows unbounded; in production wire it to a
bounded ring buffer or per-iteration drain. The 95% CI inflation
is allocator noise, not aspect-dispatch overhead.
- Numbers are debug-asserts-off release. `RUSTFLAGS="-C
target-cpu=native"` shaves another ~5–10% on this host.
- Single-host result. Cross-host variance not yet characterised.