Skip to content

perf: configurable response compression#2271

Merged
nimrod-teich merged 2 commits into
mainfrom
perf/configurable-response-compression
Apr 16, 2026
Merged

perf: configurable response compression#2271
nimrod-teich merged 2 commits into
mainfrom
perf/configurable-response-compression

Conversation

@NadavLevi

@NadavLevi NadavLevi commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Description

Compression mode comparison

  CPU cost (benchmark, Apple M4)

  ┌─────────┬─────────────┬──────────────┬────────────────┬─────────────┬────────────────┐
  │ Payload │ off (ns/op) │ gzip (ns/op) │ brotli (ns/op) │ gzip vs off │ brotli vs gzip │
  ├─────────┼─────────────┼──────────────┼────────────────┼─────────────┼────────────────┤
  │ ~256 B  │       4,175 │        8,320 │         11,491 │ 2.0× slower │    1.4× slower │
  ├─────────┼─────────────┼──────────────┼────────────────┼─────────────┼────────────────┤
  │ ~16 KB  │       6,787 │       18,842 │         59,676 │ 2.8× slower │    3.2× slower │
  ├─────────┼─────────────┼──────────────┼────────────────┼─────────────┼────────────────┤
  │ ~1 MB   │     104,720 │      465,923 │        724,516 │ 4.5× slower │    1.6× slower │
  └─────────┴─────────────┴──────────────┴────────────────┴─────────────┴────────────────┘

  Throughput (MB/s) tells the same story: off ≫ gzip ≫ brotli.

  Wire savings (synthetic; ratios inflated)

  ┌─────────┬────────────┬──────────────┐
  │ Payload │ gzip saved │ brotli saved │
  ├─────────┼────────────┼──────────────┤
  │ ~256 B  │      76.0% │        54.3% │
  ├─────────┼────────────┼──────────────┤
  │ ~16 KB  │      95.8% │        95.4% │
  ├─────────┼────────────┼──────────────┤
  │ ~1 MB   │      96.6% │        96.3% │
  └─────────┴────────────┴──────────────┘

  Gzip ties or beats brotli on savings at every size here (because brotli quality=0 is weaker at long-repeat detection than gzip BestSpeed). Real-world JSON-RPC will compress closer to 3–5× for both, but the
  relative ranking holds.

  Bottom line

  - Brotli costs dramatically more CPU for ~zero extra bandwidth savings on JSON-RPC payloads. The penalty peaks at the 16 KB bucket — exactly where typical responses land — where brotli is 3.2× slower than gzip.
  - Gzip is the right default. Matches or beats brotli on savings, 2–3× cheaper to compute, and universally supported.
  - Off is only worth it when an upstream ingress/CDN is already compressing (or for debugging). CPU savings vs gzip: another 2–4×, but you pay for it with ~95% more bytes on the wire.

Closes: #XXXX


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • read the contribution guide
  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the main branch
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

@NadavLevi NadavLevi changed the title Perf/configurable response compression pref: configurable response compression Apr 14, 2026
@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.17949% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
protocol/rpcconsumer/rpcconsumer.go 0.00% 2 Missing ⚠️
protocol/rpcsmartrouter/rpcsmartrouter.go 0.00% 2 Missing ⚠️
protocol/chainlib/common.go 97.14% 1 Missing ⚠️
Flag Coverage Δ
consensus 8.98% <ø> (ø)
protocol 35.30% <87.17%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
protocol/common/cobra_common.go 0.00% <ø> (ø)
protocol/chainlib/common.go 59.91% <97.14%> (+7.06%) ⬆️
protocol/rpcconsumer/rpcconsumer.go 7.67% <0.00%> (-0.03%) ⬇️
protocol/rpcsmartrouter/rpcsmartrouter.go 9.74% <0.00%> (-0.02%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@NadavLevi NadavLevi changed the title pref: configurable response compression perf: configurable response compression Apr 14, 2026
@github-actions

github-actions Bot commented Apr 14, 2026

Copy link
Copy Markdown

Test Results

0 tests  ±0   0 ✅ ±0   0s ⏱️ ±0s
0 suites ±0   0 💤 ±0 
7 files   ±0   0 ❌ ±0 

Results for commit 24eca2d. ± Comparison against base commit 2d92617.

♻️ This comment has been updated with latest results.

Comment thread protocol/chainlib/common.go
Comment thread protocol/chainlib/common.go
NadavLevi and others added 2 commits April 15, 2026 20:05
…ip over brotli

The client-facing fiber compress middleware was the single largest CPU hog on
the eth router after the passthrough and SendBytes fixes — 28% / 408s of a 900s
window, dominated by fasthttp.nonblockingWriteBrotli. The Go brotli
implementation (andybalholm/brotli) at LevelBestSpeed runs at ~60 MB/s/core
versus gzip BestSpeed at ~150–200 MB/s/core, and the extra wire-size savings
over gzip are marginal for typical JSON-RPC payloads.

Introduce a --response-compression flag (values: gzip, brotli, off) threaded
through ConsumerCmdFlags to both rpcconsumer and rpcsmartrouter. Default is
gzip: the middleware still runs, but a tiny pre-middleware strips `br` from
Accept-Encoding so fasthttp's encoder selects gzip. Ops can opt back into the
old brotli behavior per-deployment, or disable compression entirely when the
process is behind a compressing ingress.

Covered by tests for the Accept-Encoding stripper (token-aware, q-value-aware,
case-insensitive) and for each mode's observed Content-Encoding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d sizes

Adds two helpers for evaluating the three response-compression modes (off,
gzip, brotli) introduced in the previous commit:

- BenchmarkResponseCompression exercises the full fiber middleware chain at
  small (~256B), medium (~16KB), and large (~1MB) JSON-RPC-shaped payloads.
  Huge buckets (128MB, 1GB) are gated behind LAVA_BENCH_HUGE=1 to avoid
  accidental multi-minute runs and large allocations on CI.
- TestCompressionRatios prints an at-a-glance table of original vs encoded
  bytes and the savings percentage per (size, mode). Logs only; never fails.

Both share a synthetic JSON-RPC generator so the numbers are reproducible.
The generator docstring flags that the repeating zero-padded hex compresses
better than real-world bodies, so ratios should be read as upper bounds while
CPU throughput numbers remain representative.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@NadavLevi NadavLevi force-pushed the perf/configurable-response-compression branch from 6688c1e to 24eca2d Compare April 15, 2026 17:05
@NadavLevi NadavLevi requested a review from avitenzer April 15, 2026 17:07
@nimrod-teich nimrod-teich merged commit e542b71 into main Apr 16, 2026
30 checks passed
@nimrod-teich nimrod-teich deleted the perf/configurable-response-compression branch April 16, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants