Skip to content

tranport: Reduce heap allocs by setting BufferSlice capacity#8797

Merged
arjan-bal merged 3 commits intogrpc:masterfrom
arjan-bal:transport-heap-allocs
Jan 7, 2026
Merged

tranport: Reduce heap allocs by setting BufferSlice capacity#8797
arjan-bal merged 3 commits intogrpc:masterfrom
arjan-bal:transport-heap-allocs

Conversation

@arjan-bal
Copy link
Copy Markdown
Contributor

The change sets an initial estimate for the mem.BufferSlice capacity while reading messages to avoid reallocations for messages larger than 16KB.

Benchmarks

$ go run benchmark/benchresult/main.go streaming-before streaming-after                
streaming-networkMode_Local-bufConn_true-keepalive_false-benchTime_1m0s-trace_false-latency_0s-kbps_0-MTU_0-maxConcurrentC
alls_120-reqSize_16500B-respSize_16500B-compressor_off-channelz_false-preloader_false-clientReadBufferSize_-1-clientWriteB
ufferSize_-1-serverReadBufferSize_-1-serverWriteBufferSize_-1-sleepBetweenRPCs_0s-connections_1-recvBufferPool_simple-shar
edWriteBuffer_false
               Title       Before        After Percentage
            TotalOps      5040044      5024089    -0.32%
             SendOps            0            0      NaN%
             RecvOps            0            0      NaN%
            Bytes/op     75499.82     75446.71    -0.07%
           Allocs/op        26.24        24.22    -7.62%
             ReqT/op 11088096800.00 11052995800.00    -0.32%
            RespT/op 11088096800.00 11052995800.00    -0.32%
            50th-Lat   1.215848ms    1.22471ms     0.73%
            90th-Lat   2.258081ms    2.25736ms    -0.03%
            99th-Lat    2.78024ms   2.756574ms    -0.85%
             Avg-Lat   1.427389ms   1.431989ms     0.32%
           GoVersion     go1.24.8     go1.24.8
         GrpcVersion   1.79.0-dev   1.79.0-dev

RELEASE NOTES:

  • transport: Reduce slice re-allocations by reserving slice capacity.

@arjan-bal arjan-bal added this to the 1.79 Release milestone Jan 2, 2026
@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 Jan 2, 2026
@arjan-bal arjan-bal requested a review from mbissa January 2, 2026 10:30
@arjan-bal arjan-bal requested a review from easwars January 5, 2026 10:40
@arjan-bal arjan-bal assigned easwars and unassigned easwars and mbissa Jan 5, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.36%. Comparing base (88ac703) to head (b01f07f).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8797      +/-   ##
==========================================
+ Coverage   83.30%   83.36%   +0.06%     
==========================================
  Files         418      418              
  Lines       32897    33010     +113     
==========================================
+ Hits        27404    27520     +116     
+ Misses       4093     4088       -5     
- Partials     1400     1402       +2     
Files with missing lines Coverage Δ
internal/transport/transport.go 89.06% <100.00%> (+0.35%) ⬆️

... and 38 files with indirect coverage changes

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

@easwars
Copy link
Copy Markdown
Contributor

easwars commented Jan 5, 2026

The 50th percentile latency has gone up in the benchmarks:

            50th-Lat   1.215848ms    1.22471ms     0.73%

What was the motivation behind this change?

Comment thread internal/transport/transport.go Outdated
Comment thread internal/transport/transport.go Outdated
@easwars easwars assigned arjan-bal and unassigned easwars and mbissa Jan 5, 2026
@arjan-bal
Copy link
Copy Markdown
Contributor Author

arjan-bal commented Jan 6, 2026

The 50th percentile latency has gone up in the benchmarks:

            50th-Lat   1.215848ms    1.22471ms     0.73%

The minor regression (-0.3% QPS, +0.73% latency) is statistically insignificant. I verified across multiple runs that results vary by less than 1%. Technically, pre-allocating the BufferSlice is more efficient than initializing with zero capacity and growing it incrementally, so the performance impact should be neutral or positive. This should be true until gRPC supports larger data frames.

What was the motivation behind this change?

While working on replacing the bufio.Reader to avoid copies, I was debugging the slight increase in heap allocations. The zero copy optimizations in this branch may produce up to 2x the number of buffers than produced presently. Setting the buffer capacity correctly avoid these extra allocations.

@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Jan 6, 2026
@easwars easwars assigned arjan-bal and unassigned easwars Jan 7, 2026
@arjan-bal arjan-bal merged commit a887d0b into grpc:master Jan 7, 2026
14 checks passed
@arjan-bal arjan-bal deleted the transport-heap-allocs branch January 16, 2026 08:46
mbissa pushed a commit to mbissa/grpc-go that referenced this pull request Feb 16, 2026
The change sets an initial estimate for the `mem.BufferSlice` capacity
while reading messages to avoid reallocations for messages larger than
16KB.

## Benchmarks
```sh
$ go run benchmark/benchresult/main.go streaming-before streaming-after                
streaming-networkMode_Local-bufConn_true-keepalive_false-benchTime_1m0s-trace_false-latency_0s-kbps_0-MTU_0-maxConcurrentC
alls_120-reqSize_16500B-respSize_16500B-compressor_off-channelz_false-preloader_false-clientReadBufferSize_-1-clientWriteB
ufferSize_-1-serverReadBufferSize_-1-serverWriteBufferSize_-1-sleepBetweenRPCs_0s-connections_1-recvBufferPool_simple-shar
edWriteBuffer_false
               Title       Before        After Percentage
            TotalOps      5040044      5024089    -0.32%
             SendOps            0            0      NaN%
             RecvOps            0            0      NaN%
            Bytes/op     75499.82     75446.71    -0.07%
           Allocs/op        26.24        24.22    -7.62%
             ReqT/op 11088096800.00 11052995800.00    -0.32%
            RespT/op 11088096800.00 11052995800.00    -0.32%
            50th-Lat   1.215848ms    1.22471ms     0.73%
            90th-Lat   2.258081ms    2.25736ms    -0.03%
            99th-Lat    2.78024ms   2.756574ms    -0.85%
             Avg-Lat   1.427389ms   1.431989ms     0.32%
           GoVersion     go1.24.8     go1.24.8
         GrpcVersion   1.79.0-dev   1.79.0-dev
```

RELEASE NOTES:
* transport: Reduce slice re-allocations by reserving slice capacity.
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. Type: Performance Performance improvements (CPU, network, memory, etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants