Skip to content

feat: implement application-level compression for consumer-provider communication#2101

Merged
nimrod-teich merged 6 commits into
mainfrom
provider-consumer-compression
Nov 20, 2025
Merged

feat: implement application-level compression for consumer-provider communication#2101
nimrod-teich merged 6 commits into
mainfrom
provider-consumer-compression

Conversation

@nimrod-teich

Copy link
Copy Markdown
Contributor
  • Add custom compression logic in protocol/common/compression.go

    • CompressData: compress payloads > 10KB using gzip.BestSpeed
    • DecompressData: decompress gzip data
    • Size-based logic: only compress if it reduces size
  • Implement custom header system to bypass grpc-web wrapper issues

    • lava-compression-support: consumer signals compression capability
    • lava-compression: provider indicates compressed response
    • Replaces reliance on grpc-accept-encoding (always present)
  • Consumer side (protocol/rpcconsumer/rpcconsumer_server.go)

    • Send lava-compression-support header when flag enabled
    • Detect and decompress responses with lava-compression header
    • Handle decompression errors gracefully
  • Provider side (protocol/rpcprovider/rpcprovider_server.go)

    • Check lava-compression-support header from consumer
    • Compress responses > 10KB when consumer supports it
    • Set lava-compression header on compressed responses
    • Skip compression if it doesn't reduce size
  • Update provider listener with compression support info

This implementation works around the grpc-web wrapper stripping native gRPC compression headers (grpc-encoding), enabling compression for large payloads (15-45 MB) to reduce bandwidth usage by 70-85%.

Controlled by existing flag:
--allow-grpc-compression-for-consumer-provider-communication

Description

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

@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Nov 9, 2025
@nimrod-teich nimrod-teich force-pushed the provider-consumer-compression branch 2 times, most recently from 187bb81 to d017e35 Compare November 9, 2025 14:10
@github-actions

github-actions Bot commented Nov 9, 2025

Copy link
Copy Markdown

Test Results

2 994 tests  +37   2 993 ✅ +37   23m 9s ⏱️ - 10m 10s
  125 suites  -  1       1 💤 ± 0 
    6 files    -  1       0 ❌ ± 0 

Results for commit 0cc3a80. ± Comparison against base commit af7b939.

This pull request removes 1 and adds 38 tests. Note that renamed tests count towards both.
github.com/lavanet/lava/v5/testutil/e2e ‑ TestLavaProtocol
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_AboveThreshold
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_BelowThreshold
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_CustomThreshold
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_ExactThreshold
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_IncompressibleData
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_LargePayload
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressData_OneByteAboveThreshold
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressDecompress_RoundTrip
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressDecompress_RoundTrip/JSON-like_data
github.com/lavanet/lava/v5/protocol/common ‑ TestCompressDecompress_RoundTrip/Large_binary-like_data
…

♻️ This comment has been updated with latest results.

@nimrod-teich nimrod-teich force-pushed the provider-consumer-compression branch from d017e35 to a9cd8f3 Compare November 9, 2025 14:45
avitenzer
avitenzer previously approved these changes Nov 20, 2025
nimrod-teich and others added 5 commits November 20, 2025 17:20
…ommunication

- Add custom compression logic in protocol/common/compression.go
  - CompressData: compress payloads > 10KB using gzip.BestSpeed
  - DecompressData: decompress gzip data
  - Size-based logic: only compress if it reduces size

- Implement custom header system to bypass grpc-web wrapper issues
  - lava-compression-support: consumer signals compression capability
  - lava-compression: provider indicates compressed response
  - Replaces reliance on grpc-accept-encoding (always present)

- Consumer side (protocol/rpcconsumer/rpcconsumer_server.go)
  - Send lava-compression-support header when flag enabled
  - Detect and decompress responses with lava-compression header
  - Handle decompression errors gracefully

- Provider side (protocol/rpcprovider/rpcprovider_server.go)
  - Check lava-compression-support header from consumer
  - Compress responses > 10KB when consumer supports it
  - Set lava-compression header on compressed responses
  - Skip compression if it doesn't reduce size

- Update provider listener with compression support info

This implementation works around the grpc-web wrapper stripping
native gRPC compression headers (grpc-encoding), enabling compression
for large payloads (15-45 MB) to reduce bandwidth usage by 70-85%.

Controlled by existing flag:
--allow-grpc-compression-for-consumer-provider-communication
Unit Tests (compression_test.go):
- Test CompressData with data below/at/above threshold
- Test CompressData with incompressible data
- Test DecompressData with valid and invalid gzip data
- Test full compression/decompression round-trip cycles
- Test edge cases (exact threshold, one byte above threshold)
- Test large payloads similar to real RPC responses (15MB)
- Add benchmarks for different payload sizes (10KB, 100KB, 1MB)
- Achieves 99.54% compression on large test payloads

Integration Tests (compression_integration_test.go):
- TestCompressionHeadersConsumerToProvider: Verify consumer sets compression support header
- TestCompressionHeadersProviderToConsumer: Verify provider sets compression header
- TestConsumerDecompressionFlow: Test complete consumer decompression logic
- TestProviderCompressionDecisionFlow: Test provider's decision logic
- TestEndToEndCompressionFlow: Full integration test simulating consumer->provider->consumer
  - With compression enabled (99.3% compression ratio)
  - Without compression support
- TestCompressionWithRealGzipData: Verify compatibility with standard gzip
- TestCompressionWithIncompressibleData: Test behavior with random data

Total: 21 test cases + 6 benchmarks, all passing
@nimrod-teich nimrod-teich force-pushed the provider-consumer-compression branch from 0cc3a80 to 454ed78 Compare November 20, 2025 15:21
@nimrod-teich nimrod-teich force-pushed the provider-consumer-compression branch from 454ed78 to 5e6be70 Compare November 20, 2025 15:22
@nimrod-teich nimrod-teich merged commit f3fd615 into main Nov 20, 2025
27 of 28 checks passed
@nimrod-teich nimrod-teich deleted the provider-consumer-compression branch November 20, 2025 16:02
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