Skip to content

perf(client): borrow request headers when nothing is merged; no copy into the request target - #9

Merged
casibbald merged 1 commit into
integration/microscaler-forkfrom
perf/client-header-borrow
Oct 27, 2026
Merged

casibbald merged 1 commit into
integration/microscaler-forkfrom
perf/client-header-borrow

Conversation

@casibbald

Copy link
Copy Markdown

What

Two allocation cuts in the pooled Client's request path:

  • prepare_attempt_headers returns Cow<HeaderMap>. With no default headers, no metadata provider and no credentials to strip (the common case), the request's own map is used as is, instead of building a merged copy and cloning every value per attempt.
  • origin_form hands its String to Uri::try_from instead of parse(), which copied it.

Behaviour is unchanged: when there is anything to merge or strip, the merged map is built as before.

Numbers

examples/bench_client pool, 16 coroutines, 2000 requests each, against examples/bench_server on loopback (ms02), three rounds. Allocations per request are deterministic; req/s moved with host load (18 to 25) and is within noise.

request allocs/req before after
GET / 25.1 24.1
POST 512 B 28.1 27.1
GET with 5 KiB of headers 29.1 26.1

Tests

cargo fmt --check, clippy (default and all features, all targets), and the full suite with all features (310 passed) and with default features, on Rust 1.99.0.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y3TSRmEZAYU6RBUXhkn7WF

…ge; no copy into the request target

- `prepare_attempt_headers` rebuilt a merged `HeaderMap` for every attempt:
  defaults, then provider metadata, then the request's headers, each value
  cloned. With no default headers, no metadata provider and nothing to
  strip (the common case), the request's own map is used as is
  (`Cow::Borrowed`). That saves the map's allocations and a clone of every
  value; the first clone of a value built with `HeaderValue::from_str`
  allocates, because it promotes the bytes to shared.
- `origin_form` built the request target in a `String` and then `parse()`
  copied it into the `Uri`. `Uri::try_from(String)` takes the buffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y3TSRmEZAYU6RBUXhkn7WF
@casibbald
casibbald merged commit 3d482fd into integration/microscaler-fork Oct 27, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant