Skip to content

Avoid duplicate header parsing during JWT decoding - #543

Merged
arckoor merged 3 commits into
Keats:masterfrom
benni-rogge:perf/decode-header-once
Sep 24, 2026
Merged

arckoor merged 3 commits into
Keats:masterfrom
benni-rogge:perf/decode-header-once

Conversation

@benni-rogge

@benni-rogge benni-rogge commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Split each JWT and parse its header only once in decode. Reuse that header for provider selection, signature verification, and the returned token data. Remove the now-redundant private helper. Algorithm checks, signature verification, claims validation, and the public API remain unchanged.

The benchmark-only first commit fixes the decode fixture to contain matching claims and a valid expiration. It checks successful decoding, adds custom-header decode coverage, and gives encode cases distinct names. The same corrected workloads were used for both measurements.

Benchmark evidence

Criterion 0.8.2, 100 samples per case, 3-second warm-up, 5-second measurement. Apple M5 Pro, macOS arm64, rustc 1.98.1. Baseline source: 4c0ae752e9ac, with the benchmark corrections applied before measuring.

Mean wall-clock time per successful HS256 decode:

Backend Header Before After Reduction Reduction, 95% CI
rust_crypto Standard 1160.42 ns 997.65 ns 14.03% 13.74–14.31%
rust_crypto One custom header 1496.11 ns 1218.65 ns 18.55% 18.32–18.77%
aws_lc_rs Standard 871.89 ns 687.16 ns 21.19% 20.78–21.58%
aws_lc_rs One custom header 1126.13 ns 824.95 ns 26.74% 26.29–27.14%

These are four measurements of the same optimization, not accumulated gains. Every confidence interval clears 10%. Results apply to the small HS256 tokens in this benchmark, not all algorithms or payload sizes.

The unchanged encode implementation served as a control: mean timings ranged from 2.6% faster to 1.2% slower.

Reproduce

Run the baseline commands at the benchmark-only first commit, then the comparisons at the PR head. Preserve the generated Cargo.lock and target/ between runs.

# Before the source optimization
cargo bench --features rust_crypto --bench jwt -- --save-baseline before-rust-crypto --noplot
cargo bench --locked --features aws_lc_rs --bench jwt -- --save-baseline before-aws-lc --noplot

# After the source optimization
cargo bench --locked --features rust_crypto --bench jwt -- --baseline before-rust-crypto --noplot
cargo bench --locked --features aws_lc_rs --bench jwt -- --baseline before-aws-lc --noplot

Verification

  • cargo fmt --check: passed.
  • cargo clippy --locked --all-targets --features <backend> -- -D warnings: passed for both backends.
  • cargo test --locked --features <backend>: 108 tests passed for each backend.
  • cargo test --locked --no-default-features --features <backend>: 86 tests passed for each backend.

Here <backend> is rust_crypto or aws_lc_rs. No-default-feature tests emit unused-import and dead-code warnings in untouched test code. The MSRV/nightly/Wasm matrix was not run locally.

Prepared with AI assistance; all reported benchmarks and checks were executed locally.

Assisted-By: devx/dcd17996-cea9-431c-837c-66a5b73abb5e
Assisted-By: devx/dcd17996-cea9-431c-837c-66a5b73abb5e
@benni-rogge
benni-rogge marked this pull request as ready for review September 18, 2026 14:00
Comment thread CHANGELOG.md Outdated
@arckoor
arckoor self-requested a review September 23, 2026 18:19

@arckoor arckoor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@arckoor
arckoor merged commit dcea70f into Keats:master Sep 24, 2026
10 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.

2 participants