Measured 8 September 2026. This report replaces the single-run route-search headline with distributions over an explicitly bounded workload. It tests released crates and public historical Ethereum state; no transaction was signed or broadcast.
The 117-pool basket loaded in 1,993.8 ms p50 across 50 fresh processes (p95 4,334.9 ms, min 1,789.2 ms, max 5,186.9 ms). This times pool cold-loading only: cache construction, discovery, graph construction, liquidity-index refresh, and priming searches are separate. It is not total process-to-readiness latency.
Warm search results, in milliseconds:
| Route | Measured runs | Heuristic p50 | Heuristic p95 | Heuristic max | Exhaustive completion p50 |
|---|---|---|---|---|---|
| 10 WETH -> USDC | 300 | 3.77 | 4.29 | 47.73 | 151.03 |
| 100 LINK -> AAVE | 300 | 8.43 | 16.51 | 117.90 | 353.71 |
| 1000 DAI -> UNI | 300 | 7.06 | 10.88 | 50.20 | 847.57 |
Each heuristic winner matched the exhaustive reference in all 900/900 measured iterations, with zero measured-loop RPC requests and zero failed searches. These are repeated timings of nine route/block combinations, not 900 independent market opportunities or a general proof of optimality. Heuristic timing ends at heuristic completion; the exhaustive continuation runs afterward and is reported separately. Do not label the heuristic timing as exhaustive-search completion or event-to-submission latency. All measured outliers remain in the dataset.
Full-range V3 extraction loads globals, every initialized tick found by scanning
the full bitmap, and the observation ring. Each row has 90 measured repetitions
and one eth_call per extraction:
| Pool | Initialized ticks | Observations | p50 ms | p95 ms | Max ms |
|---|---|---|---|---|---|
| USDC/WETH 0.05% | 1,552 | 723 | 74.75 | 99.21 | 1303.43 |
| USDC/WETH 0.3% | 686 | 1,440 | 50.16 | 68.91 | 1056.99 |
| DAI/WETH 0.3% | 492 | 1,500 | 47.11 | 65.51 | 123.01 |
| All three in one call | 2,730 | 3,663 | 121.01 | 157.81 | 213.02 |
Individual and batched decoded states matched exactly in 99/99 checks,
including warmups. This checks batching equivalence against the individual full
extraction path; it is not an independent proof of every storage value. The
measured transport recorded one HTTP packet and one eth_call for each single
or three-pool extraction. It does not establish a one-call capacity for 117 pools.
evm-amm-search 0.2.0, evm-amm-state 0.3.0, and
evm-fork-cache 0.4.0; exact dependencies in Cargo.lock.(n-1)*0.95.
Per-block breakdowns, minima, maxima, and RPC totals are in results/summary.json.The pre-collection smoke test found that one 117-pool extraction returned 2,458,400 bytes against this endpoint's 1,000,000-byte return limit. The final collection therefore uses batches of at most 16 pools. The published cold-load numbers include this practical batching configuration, not a hypothetical single request. Rate-limited smoke tests and an exploratory second-provider check were configuration diagnostics and are excluded from the declared main collection.
Across the 50 measured cold-load phases, the transport counted 800 eth_calls,
50 eth_getAccountInfo probes, and 300 standard account-read requests in 1,150
HTTP packets. Thirty probes returned method-unavailable responses; the supported
fallback completed successfully. There were no failed pool initializations or
liquidity-refresh failures in the formal run. Capability fallbacks are retained
in the timings and raw logs.
The older 997.2 ms cold-load / 4.37–9.78 ms warm-search observation used an earlier release and environment. It remains historical evidence, not an apples-to-apples speedup baseline. The separate Aave liquidation fixture was not rerun here. These infrastructure timings do not measure transaction submission, inclusion, settlement, or strategy return.
The route harness adapts the published evm-amm-search 0.2.0
examples/docs_route_benchmark.rs; the full-sync harness uses public
evm-amm-state / evm-fork-cache APIs. Source and the locked dependency graph
are included. The runner needs an archive endpoint supporting state overrides.
It reads the URL from the environment and redacts it from retained logs.
cargo build --release --locked --bins
# Set E2E_RPC_URL in your environment; do not commit credentials.
python3 run_benchmarks.py
python3 summarize.py
Use a copy of this directory to rerun without overwriting the retained results.
The runner fixes sampling and workload before collection. The summarizer checks
sample counts, unchanged pool membership, pool readiness, warm-search success and
RPC counts, batch parity, and single-call accounting before writing summaries.
results/measurements.jsonl contains all measured rows plus warmups;
results/*.log and their metadata retain the original redacted output and hashes.
successful-build-binaries.json identifies the actual tested release binaries.
SHA256SUMS binds the published evidence files.