Skip to content

Benchmarks

This page records local benchmark results for the official Anvil HTTP drivers. It is a measurement report, not a portability guarantee. Run the same command on your own target hardware before using these numbers for capacity planning.

For the live-server results below, one operation is one completed HTTP request over a real TCP connection to a running local server.

MetricMeaning
Requests/secCompleted HTTP requests per second during the measured window.
p50Half of completed requests finished at or below this latency.
p9595% of completed requests finished at or below this latency.
p9999% of completed requests finished at or below this latency.
ErrorsRequests that returned the wrong status, missed an expected header, or failed at the client.

Go microbenchmarks use different terms:

MetricMeaning
ns/opNanoseconds per in-process benchmark operation.
B/opHeap bytes allocated per operation.
allocs/opHeap allocation count per operation.

Microbenchmarks are useful for driver overhead and regressions. Live-server benchmarks are better for user-facing throughput and latency discussion.

The live workload uses the same generated-style sdk.HTTPRoute shape for each driver:

  • POST /projects/:projectID/events?tenant=acme&include=audit
  • Route parameter read: projectID
  • Query read: tenant
  • Header read: X-Request-ID
  • Middleware before hook writes request-local state
  • Middleware after hook writes X-Benchmark-After
  • JSON body decode
  • Validation-style checks for required fields
  • Deterministic checksum work with SHA-256
  • JSON response encode

The request body is:

{
"name": "deploy",
"quantity": 7,
"tags": ["api", "bench", "native"],
"metadata": {
"region": "eu",
"tier": "gold",
"source": "livebench"
}
}

Run from the anvil-http/benchmarks module:

Terminal window
go run ./cmd/livebench `
-drivers native,std,fiber `
-concurrency 16,64,256 `
-repeats 3 `
-warmup 2s `
-duration 10s `
-out artifacts/livebench/20260606-project-work

The runner starts one driver at a time on 127.0.0.1, warms it up, measures the selected concurrency level, shuts it down, and then moves to the next driver. Drivers are interleaved by repeat and concurrency to reduce time-order bias.

FieldValue
Date2026-06-06
OS/ArchWindows / amd64
Gogo1.26.4
CPUAMD Ryzen 9 7950X3D 16-Core Processor
Logical CPUs32
Scenarioproject-work
Warmup2s per driver/concurrency/repeat
Measurement10s per driver/concurrency/repeat
Repeats3

Live project-work throughput by driver and concurrency

Requests/sec values are averages across repeats, rounded to whole requests.

DriverConcurrencyRepeatsRequests/secErrors
fiber16366,0300
native16348,1930
std16333,0420
fiber643163,7320
native643144,4880
std64395,7150
fiber2563202,8850
native2563183,6850
std2563165,9350

Live project-work p95 latency by driver and concurrency

DriverConcurrencyp50 msp95 msp99 ms
fiber160.0001.0101.218
native160.3021.0181.521
std160.5051.0341.528
fiber640.0001.6202.559
native640.0002.0272.840
std640.5042.5393.892
fiber2560.5045.2617.666
native2560.5045.7618.459
std2560.5046.1459.741

Some p50 values round to 0.000ms on this Windows run because many local keep-alive requests completed below the displayed millisecond precision. Use p95 and p99 when comparing latency behavior from this report.

These results describe one local run. They can move with CPU scheduling, power profile, background processes, Go version, driver version, and workload shape.

The useful information is the shape of the results: how each driver behaves as concurrency rises, and which latency percentile matters for the application you are sizing.