Skip to content

Conversation

@arjan-bal
Copy link
Contributor

@arjan-bal arjan-bal commented Oct 16, 2025

This change incorporates changes from golang/go#73560 to split reading HTTP/2 frame headers and payloads. If the frame is not a Data frame, it's read through the standard library framer as before. For Data frames, the payload is read directly into a buffer from the buffer pool to avoid copying it from the framer's buffer.

Testing

For 1 MB payloads, this results in ~4% improvement in throughput.

# test command
go run benchmark/benchmain/main.go -benchtime=60s -workloads=streaming \
   -compression=off -maxConcurrentCalls=120 -trace=off \
   -reqSizeBytes=1000000 -respSizeBytes=1000000 -networkMode=Local -resultFile="${RUN_NAME}"

# comparison
go run benchmark/benchresult/main.go streaming-before streaming-after  
               Title       Before        After Percentage
            TotalOps        87536        91120     4.09%
             SendOps            0            0      NaN%
             RecvOps            0            0      NaN%
            Bytes/op   4074102.92   4070489.30    -0.09%
           Allocs/op        83.60        76.55    -8.37%
             ReqT/op 11671466666.67 12149333333.33     4.09%
            RespT/op 11671466666.67 12149333333.33     4.09%
            50th-Lat  78.209875ms  75.159943ms    -3.90%
            90th-Lat 117.764228ms   107.8697ms    -8.40%
            99th-Lat 146.935704ms 139.069685ms    -5.35%
             Avg-Lat  82.310691ms  79.073282ms    -3.93%
           GoVersion     go1.24.7     go1.24.7
         GrpcVersion   1.77.0-dev   1.77.0-dev

For smaller payloads, the difference in minor.

go run benchmark/benchmain/main.go -benchtime=60s -workloads=streaming \
   -compression=off -maxConcurrentCalls=120 -trace=off \
   -reqSizeBytes=100 -respSizeBytes=100 -networkMode=Local -resultFile="${RUN_NAME}"

go run benchmark/benchresult/main.go streaming-before streaming-after 
               Title       Before        After Percentage
            TotalOps     21490752     21477822    -0.06%
             SendOps            0            0      NaN%
             RecvOps            0            0      NaN%
            Bytes/op      1902.92      1902.94     0.00%
           Allocs/op        29.21        29.21     0.00%
             ReqT/op 286543360.00 286370960.00    -0.06%
            RespT/op 286543360.00 286370960.00    -0.06%
            50th-Lat    352.505µs    352.247µs    -0.07%
            90th-Lat    433.446µs    434.907µs     0.34%
            99th-Lat    536.445µs    539.759µs     0.62%
             Avg-Lat    333.403µs    333.457µs     0.02%
           GoVersion     go1.24.7     go1.24.7
         GrpcVersion   1.77.0-dev   1.77.0-dev

RELEASE NOTES:

  • transport: Avoid a buffer copy when reading data.

@arjan-bal arjan-bal added this to the 1.77 Release milestone Oct 16, 2025
@arjan-bal arjan-bal added Type: Performance Performance improvements (CPU, network, memory, etc) Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. labels Oct 16, 2025
@codecov
Copy link

codecov bot commented Oct 16, 2025

Codecov Report

❌ Patch coverage is 92.40506% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.92%. Comparing base (b8a0fc9) to head (8ef2d03).
⚠️ Report is 10 commits behind head on master.

Files with missing lines Patch % Lines
internal/transport/http_util.go 93.65% 2 Missing and 2 partials ⚠️
internal/transport/http2_client.go 83.33% 0 Missing and 1 partial ⚠️
internal/transport/http2_server.go 90.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8657      +/-   ##
==========================================
+ Coverage   81.92%   82.92%   +0.99%     
==========================================
  Files         416      417       +1     
  Lines       40789    32369    -8420     
==========================================
- Hits        33418    26843    -6575     
+ Misses       6000     4147    -1853     
- Partials     1371     1379       +8     
Files with missing lines Coverage Δ
mem/buffer_pool.go 100.00% <ø> (ø)
internal/transport/http2_client.go 92.41% <83.33%> (+0.14%) ⬆️
internal/transport/http2_server.go 91.41% <90.00%> (+0.28%) ⬆️
internal/transport/http_util.go 94.81% <93.65%> (+0.37%) ⬆️

... and 359 files with indirect coverage changes

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

@arjan-bal arjan-bal force-pushed the copyless-data-frame-read branch from b5f777e to ae8c8df Compare October 16, 2025 16:54
@arjan-bal arjan-bal self-assigned this Oct 16, 2025
@arjan-bal arjan-bal force-pushed the copyless-data-frame-read branch 2 times, most recently from efe661b to 778af0a Compare October 16, 2025 18:53
@arjan-bal arjan-bal force-pushed the copyless-data-frame-read branch from 778af0a to 45e856f Compare October 16, 2025 19:12
@arjan-bal arjan-bal force-pushed the copyless-data-frame-read branch from 45e856f to 5ec4a4e Compare October 16, 2025 19:15
@arjan-bal arjan-bal removed their assignment Oct 16, 2025
@arjan-bal arjan-bal requested review from dfawley and easwars and removed request for easwars October 16, 2025 19:21
@easwars easwars assigned arjan-bal and unassigned easwars Oct 16, 2025
Copy link
Contributor Author

@arjan-bal arjan-bal left a comment

Choose a reason for hiding this comment

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

I realised that the changes in the std lib framer are not imported in g3 os this PR can't be merged in gRPC yet. I've added a Blocked label to indicate this.

@arjan-bal arjan-bal removed their assignment Oct 21, 2025
@easwars
Copy link
Contributor

easwars commented Oct 27, 2025

I realised that the changes in the std lib framer are not imported in g3 os this PR can't be merged in gRPC yet. I've added a Blocked label to indicate this.

When is it expected to be imported?

@easwars easwars assigned arjan-bal and unassigned dfawley Oct 27, 2025
@arjan-bal
Copy link
Contributor Author

I realised that the changes in the std lib framer are not imported in g3 os this PR can't be merged in gRPC yet. I've added a Blocked label to indicate this.

When is it expected to be imported?

I think importing the code is self-service. I'm working on it: cl/824893868

@easwars easwars assigned dfawley and unassigned easwars and arjan-bal Oct 28, 2025
@easwars
Copy link
Contributor

easwars commented Oct 28, 2025

@dfawley: Moving to your plate in case you want to take a look. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. Status: Blocked Type: Performance Performance improvements (CPU, network, memory, etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants