Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Performance

Benchmark results from the Criterion benchmark suite in crates/volter/benches/router.rs.

These numbers are provided for transparency and may vary depending on hardware, operating system, compiler version, and runtime environment.

Test environment

AttributeValue
MachineMacBook Pro M3 Max
Memory64 GB RAM
Buildcargo bench (release)
Benchmark toolCriterion

Methodology

Each benchmark measures the wall-clock time of a single request dispatch through the framework. No real TCP socket is bound — requests are constructed in memory and dispatched directly through the router’s tower::Service::call implementation.

  • Sample size: 100 measurements per benchmark
  • Measurement time: 5 seconds per benchmark
  • Warm-up: 2 seconds before measurement begins
  • Runtime: tokio::runtime::Runtime::block_on for every iteration

Results

BenchmarkMedianDescription
static_route312.93 nsSingle static route, no extractors
path_params566.83 ns/:id pattern match + Path<i32>
query_extraction523.72 nsQuery string deserialization (Query<T>)
json_extraction610.58 nsJSON body deserialization (Json<T>)
multi_extractor792.91 nsState<App> + Path<i32> + Query<T>
middleware/bare310.01 nsPlain route, no middleware
middleware/with_layers1,291.90 ns4 middleware layers
full_pipeline338.71 nsEnd-to-end via TestClient

Observations

Router dispatch — Static routes cost ~313 ns (a hash-map lookup). Adding a path parameter (/:id) raises this to ~567 ns due to the linear scan over registered parameterised routes.

ExtractorsQuery<T> (~524 ns) and Json<T> (~611 ns) are dominated by serde deserialization. The framework overhead beyond serde is minimal (extension insertion for path params, body buffering for JSON).

Middleware — A stack of four layers (RequestId, Trace, Timeout, CatchPanic) adds ~980 ns over a bare route, or roughly 250 ns per layer on this hardware. Each layer adds a BoxCloneService wrapper and a small amount of per-request bookkeeping.

End-to-end — The TestClient pipeline (which clones the router and constructs a fresh request) adds ~26 ns compared to a direct Service::call.

Running locally

cargo bench -p volter

HTML reports with distribution plots are written to target/criterion/report/index.html.

CI

Benchmarks are tracked across commits to catch regressions. For the CI workflow, see TOOLS.md → “Benchmarking”.