<!-- https://zunderlabs.com/docs/methods/latency · Markdown version of the page -->

# The latency benchmark

How much time Guard's risk check and order signing add, how it was measured, what is not included, and how to rerun it.

## The result

Measured on Zunder's build box, an AWS Graviton `c7g.4xlarge` in `eu-central-1`, release build, 20,000 rounds (commit `1f13430`, 6 Oct 2026):

| Step | p50 | p99 |
|---|---|---|
| Risk sizing (`RiskEngine::size_entry`) | 0.3 µs | not recorded |
| Build the order action and sign it | 69 µs | 74 µs |

So the risk check is about 0.0003 ms, and the whole of Guard's own work on an order is about 0.07 ms.

## What it measures

The test `latency_of_sizing_and_signing` in `crates/zunder-exec/src/hyperliquid/signing.rs`, per round:

1. **size:** the risk engine sizes one entry from its stop (equity 2,000, entry 3,101.5, stop 3,040, 2.8 cost per unit, 35 open risk, 1,800 open value; the arithmetic is [Example 5](https://zunderlabs.com/docs/concepts/sizing#example-5-the-numbers-from-the-latency-benchmark));
2. **build+sign:** builds Hyperliquid's order action with that quantity (an IOC limit order), encodes it, hashes it, and signs it with secp256k1 as an L1 action for testnet, with a new nonce each round.

It prints p50, p99 and p99.9 for size, build+sign and the total.

## What it does not measure

- **The network.** Neither the hop from your bot to Guard nor from Guard to Hyperliquid.
- **The proxy's own work** (planned): reading the bot's request, checking the client key's signature, and re-encoding. Checking a signature is a public-key recovery, of the same order of cost as signing; we will measure it, not guess it, when the proxy exists.
- **Contention.** One thread, nothing else running. A busy laptop is slower.
- **Clock resolution.** `std::time::Instant` around sub-microsecond work rounds; the 0.3 µs is an order of magnitude, not a precise figure.

## Rerun it

From a checkout of the source, in release mode:

```sh
cargo test --release -p zunder-exec latency_of_sizing_and_signing -- --ignored --nocapture
```

Output looks like:

```text
      size: p50     0.3 us  p99     … us  p99.9     … us
build+sign: p50    69.0 us  p99    74.0 us  p99.9     … us
     total: p50     … us  p99     … us  p99.9     … us
```

Numbers differ by machine. Please report yours with the CPU and the commit.

:::note[Planned]
When Guard ships, the benchmark ships in its source too, extended by the proxy's steps, and the website will show the full path from request in to request out.
:::
