Skip to content

mem: Add faster tiered buffer pool - #8775

Merged
arjan-bal merged 8 commits into
grpc:masterfrom
arjan-bal:effecient-tiered-buffer-pool
Feb 16, 2026
Merged

mem: Add faster tiered buffer pool#8775
arjan-bal merged 8 commits into
grpc:masterfrom
arjan-bal:effecient-tiered-buffer-pool

Conversation

@arjan-bal

@arjan-bal arjan-bal commented Dec 17, 2025

Copy link
Copy Markdown
Contributor

This change adds a new tiered buffer pool that uses power-of-2 tier sizes. It reduces the lookup time for the relevant sizedBufferPool from $O(\log n)$ to $O(1)$, where n is the number of tiers. This creates constant-time lookups independent of the tier count, allowing users to add more tiers without performance overhead.

Benchmarks

Micro-benchmark that measures only the pool query performance, ignoring the allocation time:

func BenchmarkSearch(b *testing.B) {
	defaultBufferPoolSizes := make([]int, len(defaultBufferPoolSizeExponents))
	for i, exp := range defaultBufferPoolSizeExponents {
		defaultBufferPoolSizes[i] = 1 << exp
	}
	b.Run("pool=Tiered", func(b *testing.B) {
		p := NewTieredBufferPool(defaultBufferPoolSizes...).(*tieredBufferPool)
		for b.Loop() {
			for size := range 1 << 19 {
				// One for get, one for put.
				_ = p.getPool(size)
				_ = p.getPool(size)
			}
		}
	})

	b.Run("pool=BinaryTiered", func(b *testing.B) {
		p := NewBinaryTieredBufferPool(defaultBufferPoolSizeExponents...).(*binaryTieredBufferPool)
		for b.Loop() {
			for size := range 1 << 19 {
				_ = p.poolForGet(size)
				_ = p.poolForPut(size)
			}
		}
	})
}

With 5 tiers:

go test -bench=BenchmarkSearch -count=10 -benchmem | benchstat -col '/pool' -
goos: linux
goarch: amd64
pkg: google.golang.org/grpc/mem
cpu: Intel(R) Xeon(R) CPU @ 2.60GHz
          │   Tiered    │            BinaryTiered             │
          │   sec/op    │   sec/op     vs base                │
Search-48   5.353m ± 2%   2.036m ± 0%  -61.97% (p=0.000 n=10)

          │   Tiered   │          BinaryTiered          │
          │    B/op    │    B/op     vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

          │   Tiered   │          BinaryTiered          │
          │ allocs/op  │ allocs/op   vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

With 9 tiers:

go test -bench=BenchmarkSearch -count=10 -benchmem | benchstat -col '/pool' -
goos: linux
goarch: amd64
pkg: google.golang.org/grpc/mem
cpu: Intel(R) Xeon(R) CPU @ 2.60GHz
          │   Tiered    │            BinaryTiered             │
          │   sec/op    │   sec/op     vs base                │
Search-48   5.659m ± 0%   2.035m ± 0%  -64.04% (p=0.000 n=10)

          │   Tiered   │          BinaryTiered          │
          │    B/op    │    B/op     vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

          │   Tiered   │          BinaryTiered          │
          │ allocs/op  │ allocs/op   vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

RELEASE NOTES:

  • mem: Add faster tiered buffer pool. Use NewBinaryTieredBufferPool to create such pools.

@arjan-bal arjan-bal added this to the 1.79 Release milestone Dec 17, 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 Dec 17, 2025
@arjan-bal
arjan-bal requested review from dfawley and easwars December 17, 2025 10:25
@codecov

codecov Bot commented Dec 17, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.33333% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.66%. Comparing base (81a00ce) to head (3b88c26).
⚠️ Report is 83 commits behind head on master.

Files with missing lines Patch % Lines
mem/buffer_pool.go 73.33% 10 Missing and 6 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8775      +/-   ##
==========================================
- Coverage   83.22%   80.66%   -2.56%     
==========================================
  Files         418      416       -2     
  Lines       32385    33495    +1110     
==========================================
+ Hits        26952    27019      +67     
- Misses       4050     4663     +613     
- Partials     1383     1813     +430     
Files with missing lines Coverage Δ
mem/buffer_pool.go 81.66% <73.33%> (-14.95%) ⬇️

... and 85 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 effecient-tiered-buffer-pool branch from bdccc9b to 1f26e66 Compare December 17, 2025 12:28

@easwars easwars left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I thought we decided to make it possible for the user to set the default buffer pool for the whole process through an experimental API, and get rid of the existing dial option and the server option. Was your plan to do that in a follow-up?

Comment thread mem/buffer_pool.go Outdated
Comment thread mem/buffer_pool.go Outdated
Comment thread mem/buffer_pool.go Outdated
Comment thread mem/buffer_pool.go Outdated
@easwars easwars assigned arjan-bal and unassigned easwars and dfawley Dec 17, 2025
@arjan-bal

Copy link
Copy Markdown
Contributor Author

I thought we decided to make it possible for the user to set the default buffer pool for the whole process through an experimental API, and get rid of the existing dial option and the server option. Was your plan to do that in a follow-up?

I was waiting for the author of #8770 to raise a PR for exposing a function to set the default buffer pool. See the second part of #8770 (comment).

get rid of the existing dial option and the server option

I'm not sure if we want to do this. Maybe people want to use different buffer pools for each channel.


In this PR, I'm just improving the existing buffer pool implementation.

@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Dec 18, 2025
@arjan-bal
arjan-bal force-pushed the effecient-tiered-buffer-pool branch from b50277e to 8e7ecc4 Compare December 18, 2025 19:51
@arjan-bal
arjan-bal force-pushed the effecient-tiered-buffer-pool branch from 8e7ecc4 to 36d34f7 Compare December 18, 2025 19:54
@easwars

easwars commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

Also, would it make sense to add some of the micro benchmarks that you used as part of this PR? Thanks.

@easwars easwars assigned arjan-bal and unassigned easwars Jan 20, 2026
Comment thread mem/buffer_pool.go Outdated
Comment thread mem/buffer_pool.go Outdated
Comment thread mem/buffer_pool.go Outdated
Comment thread mem/buffer_pool.go Outdated
@arjan-bal
arjan-bal force-pushed the effecient-tiered-buffer-pool branch from 3f63cea to e467b97 Compare February 3, 2026 11:15
@arjan-bal arjan-bal assigned easwars and unassigned arjan-bal Feb 3, 2026
@arjan-bal

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new binaryTieredBufferPool which provides a significant performance improvement for buffer pool lookups by using power-of-2 tier sizes for O(1) lookups. The implementation is clever, leveraging math/bits for efficient calculations. The accompanying tests are thorough, including architecture-specific checks and benchmarks that demonstrate the performance gains. I've found a minor issue in one of the new benchmark tests that could lead to a panic. Overall, this is an excellent contribution that improves performance and is well-implemented.

Comment thread mem/buffer_pool_internal_test.go
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@arjan-bal
arjan-bal force-pushed the effecient-tiered-buffer-pool branch from 1502569 to f32f229 Compare February 3, 2026 18:18

@easwars easwars left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM modulo minor nits

Comment thread mem/buffer_pool.go Outdated
Comment on lines +47 to +58
var defaultBufferPoolSizeExponents = []uint8{
8,
goPageSizeExponent,
14, // 16KB (max HTTP/2 frame size used by gRPC)
15, // 32KB (default buffer size for io.Copy)
20, // 1MB
}

var defaultBufferPool BufferPool
var (
defaultBufferPool BufferPool
uintSize = bits.UintSize // use a variable for mocking during tests.
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Group all these vars in one block, or don't have a block at all (like you currently do for consts).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Grouped all the vars and consts in a single block.

Comment thread mem/buffer_pool.go Outdated
// Allocating slices of size > 2^maxExponent isn't possible on
// maxExponent-bit machines.
if int(exp) > maxExponent {
return nil, fmt.Errorf("allocating slice of size 2^%d is not possible", exp)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: prefix the error string with package name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added the prefix.

Comment thread mem/buffer_pool.go
}

func (b *binaryTieredBufferPool) Put(buf *[]byte) {
b.poolForPut(cap(*buf)).Put(buf)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we add a comment here capturing the subtle but important fact that we are passing the capacity of the buffer, and not the size of the buffer to poolForPut. If we did the latter, all buffers would eventually move to the smallest pool.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a comment.

Comment thread mem/buffer_pool_internal_test.go Outdated
wantErr bool
}{
{
name: "32-bit valid exponent",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Make subtest names more like identifiers. go/go-style/decisions#subtest-names

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment thread mem/buffer_pool_internal_test.go Outdated
t.Errorf("NewBinaryTieredBufferPool() error = %t, wantErr %t", err, tt.wantErr)
return
}
if err == nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: invert the conditional and return early for tests where an error was expected and was seen.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

for b.Loop() {
for size := range 1 << 19 {
_ = p.poolForGet(size)
_ = p.poolForPut(size)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does it matter that we are not passing capacity here to poolForPut?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is true that this benchmark doesn't use the buffer's expected capacity, but the results should still be similar. The benchmark intentionally avoids fetching a buffer to ensure we measure only the buffer overhead, excluding allocation time. While we could determine the expected capacity by type-asserting the pool to sizedBufferPool and reading its defaultSize field, this would make the benchmark brittle by relying on a private implementation. Therefore, I am not making the change at this time.

@easwars easwars assigned arjan-bal and unassigned easwars Feb 13, 2026
@arjan-bal

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new binaryTieredBufferPool which provides O(1) lookup time for buffer pools by using power-of-2 tier sizes. The implementation is well-structured, includes comprehensive tests, and the benchmarks demonstrate a significant performance improvement over the existing tieredBufferPool. I have one suggestion to handle duplicate exponents in the pool configuration to prevent potential resource leaks.

Comment thread mem/buffer_pool.go
arjan-bal and others added 2 commits February 16, 2026 11:34
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@arjan-bal
arjan-bal merged commit 3be7e2d into grpc:master Feb 16, 2026
14 checks passed
@arjan-bal
arjan-bal deleted the effecient-tiered-buffer-pool branch February 16, 2026 06:25
Pranjali-2501 pushed a commit to Pranjali-2501/grpc-go that referenced this pull request Feb 23, 2026
This change adds a new tiered buffer pool that uses power-of-2 tier
sizes. It reduces the lookup time for the relevant sizedBufferPool from
$O(\log n)$ to $O(1)$, where n is the number of tiers. This creates
constant-time lookups independent of the tier count, allowing users to
add more tiers without performance overhead.

## Benchmarks

Micro-benchmark that measures only the pool query performance, ignoring
the allocation time:
```go
func BenchmarkSearch(b *testing.B) {
	defaultBufferPoolSizes := make([]int, len(defaultBufferPoolSizeExponents))
	for i, exp := range defaultBufferPoolSizeExponents {
		defaultBufferPoolSizes[i] = 1 << exp
	}
	b.Run("pool=Tiered", func(b *testing.B) {
		p := NewTieredBufferPool(defaultBufferPoolSizes...).(*tieredBufferPool)
		for b.Loop() {
			for size := range 1 << 19 {
				// One for get, one for put.
				_ = p.getPool(size)
				_ = p.getPool(size)
			}
		}
	})

	b.Run("pool=BinaryTiered", func(b *testing.B) {
		p := NewBinaryTieredBufferPool(defaultBufferPoolSizeExponents...).(*binaryTieredBufferPool)
		for b.Loop() {
			for size := range 1 << 19 {
				_ = p.poolForGet(size)
				_ = p.poolForPut(size)
			}
		}
	})
}
```
With 5 tiers:
```sh
go test -bench=BenchmarkSearch -count=10 -benchmem | benchstat -col '/pool' -
goos: linux
goarch: amd64
pkg: google.golang.org/grpc/mem
cpu: Intel(R) Xeon(R) CPU @ 2.60GHz
          │   Tiered    │            BinaryTiered             │
          │   sec/op    │   sec/op     vs base                │
Search-48   5.353m ± 2%   2.036m ± 0%  -61.97% (p=0.000 n=10)

          │   Tiered   │          BinaryTiered          │
          │    B/op    │    B/op     vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

          │   Tiered   │          BinaryTiered          │
          │ allocs/op  │ allocs/op   vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal
```
With 9 tiers:
```sh
go test -bench=BenchmarkSearch -count=10 -benchmem | benchstat -col '/pool' -
goos: linux
goarch: amd64
pkg: google.golang.org/grpc/mem
cpu: Intel(R) Xeon(R) CPU @ 2.60GHz
          │   Tiered    │            BinaryTiered             │
          │   sec/op    │   sec/op     vs base                │
Search-48   5.659m ± 0%   2.035m ± 0%  -64.04% (p=0.000 n=10)

          │   Tiered   │          BinaryTiered          │
          │    B/op    │    B/op     vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

          │   Tiered   │          BinaryTiered          │
          │ allocs/op  │ allocs/op   vs base            │
Search-48   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal
```

RELEASE NOTES:
* mem: Add faster tiered buffer pool. Use `NewBinaryTieredBufferPool` to
create such pools.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@ash2k

ash2k commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

I'm not sure if we want to do this. Maybe people want to use different buffer pools for each channel.

Very much agree with this. As a user, I'd prefer to not have any global state at all. I'd prefer all things to be tied to a client or to a server. I can share what I want to share across instances of these by myself. This is a more flexible approach.

vanja-p added a commit to buildbuddy-io/buildbuddy that referenced this pull request Apr 6, 2026
nschloe pushed a commit to live-clones/forgejo that referenced this pull request Jul 23, 2026
…/forgejo) (#13580)

This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [google.golang.org/grpc](https://github.com/grpc/grpc-go) | `v1.79.3` → `v1.82.1` | ![age](https://developer.mend.io/api/mc/badges/age/go/google.golang.org%2fgrpc/v1.82.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/google.golang.org%2fgrpc/v1.79.3/v1.82.1?slim=true) |

---

### gRPC-Go: xDS RBAC and HTTP/2 Vulnerabilities
[GHSA-hrxh-6v49-42gf](GHSA-hrxh-6v49-42gf)

<details>
<summary>More information</summary>

#### Details
Multiple security vulnerabilities have been identified and addressed in grpc-go affecting the xDS RBAC authorization engine (internal/xds/rbac) and the HTTP/2 transport server implementation (internal/transport). These vulnerabilities could result in:

- Authorization Bypass (Fail-Open) when translating xDS RBAC policies containing `Metadata` or `RequestedServerName` fields.
- Denial of Service (High CPU Consumption) due to an HTTP/2 Rapid Reset mitigation bypass during client-initiated stream resets.
- Denial of Service (Server Panic) when parsing crafted xDS RBAC policies containing `NOT` rules around unsupported fields.

##### Impact
_What kind of vulnerability is it? Who is impacted?_

##### xDS RBAC Authorization Bypass via `Metadata` & `RequestedServerName` matchers

- Affected Component: xDS RBAC
- Impact: When building policy matchers for gRPC RBAC from xDS configurations, unsupported `permission` and `principal` rules (specifically `Metadata` and `RequestedServerName`) were silently ignored and treated as no-ops.
  - If an authorization policy relied purely on these matchers for access control, treating those rules as no-ops effectively removed the restrictions.
- If these unsupported rules were nested inside logical `NOT` rules (`Permission_NotRule` / `Principal_NotId`) or multi-condition `OR/AND` rules, silently dropping them changed the boolean logic flow of the authorization engine.

As a result, policy evaluation decisions could fail open, allowing unauthorized clients to access protected gRPC services or resources.

##### HTTP/2 Rapid Reset Mitigation Bypass / Denial of Service via Stream Aborts

- Affected Component: HTTP/2 transport
- Impact: Earlier mitigations in grpc-go for HTTP/2 Rapid Reset only applied threshold checks to items that directly resulted in control frames being written back to the wire, such as `SETTINGS` ACKs or server-initiated `RST_STREAM`s.

When a client initiated a rapid flood of stream creation (`HEADERS`) immediately followed by stream termination `RST_STREAM`, items queued up in the control buffer without counting against the transport response frame threshold. An attacker can repeatedly trigger this flood sequence to bypass reader blocking, resulting in high CPU usage, and Denial of Service (DoS).

##### Denial of Service (Panic) in xDS RBAC Engine via Unsupported Fields inside NOT Rules

- Affected Component: xDS RBAC
- Impact: The xDS RBAC policy translators recursively generate matchers for nested rules. When a `NOT` rule wrapped an unsupported or unhandled field (such as `SourcedMetadata`), the recursive step returned an empty matcher. This could result in a runtime panic when the RBAC engine attempts to authorize an incoming request.

An attacker or misconfigured/malicious xDS management server delivering an LDS/RDS update containing a `NOT` rule around an unhandled field causes the gRPC server process to crash immediately (CWE-248 / Denial of Service).

##### Patches
_Has the problem been patched? What versions should users upgrade to?_

All three issues have been fixed in `master` and will be released in 1.82.1 shortly.

##### Workarounds
_Is there a way for users to fix or remediate the vulnerability without upgrading?_

If upgrading grpc-go immediately is not possible, apply the following workarounds based on your deployment architecture:

* For xDS RBAC Vulnerabilities & Panics: Ensure that upstream xDS management servers do not push RBAC policies containing `Metadata`, `RequestedServerName`, or `NOT` rules wrapping unsupported fields (such as `SourcedMetadata`) to grpc-go servers.
* For HTTP/2 Rapid Reset DOS: Configure upstream reverse proxies or load balancers (such as Envoy) with strict HTTP/2 `max_concurrent_streams` limits and active rate limiting on `RST_STREAM` frequency per connection.

##### Severity

  | Vulnerability | Qualitative Severity | Approximate CVSS v3.1 Score | Primary Impact |
  | :--- | :--- | :--- | :--- |
  | **xDS RBAC Authorization Bypass** | **High** | `8.2` | Unauthorized Access / Fail-Open |
  | **HTTP/2 Rapid Reset DOS Bypass** | **High** | `7.5` | High CPU Consumption / Denial of Service |
  | **xDS RBAC Engine Server Panic** | **Medium** | `5.9` | Process Crash / Denial of Service |

#### Severity
- CVSS Score: 8.8 / 10 (High)
- Vector String: `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N`

#### References
- [https://github.com/grpc/grpc-go/security/advisories/GHSA-hrxh-6v49-42gf](https://github.com/grpc/grpc-go/security/advisories/GHSA-hrxh-6v49-42gf)
- [https://github.com/grpc/grpc-go/pull/9236](https://github.com/grpc/grpc-go/pull/9236)
- [https://github.com/grpc/grpc-go/commit/4ea465d4ab98013f72a142fe0fc89c19770b2935](https://github.com/grpc/grpc-go/commit/4ea465d4ab98013f72a142fe0fc89c19770b2935)
- [https://github.com/grpc/grpc-go](https://github.com/grpc/grpc-go)
- [https://github.com/grpc/grpc-go/releases/tag/v1.82.1](https://github.com/grpc/grpc-go/releases/tag/v1.82.1)

This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-hrxh-6v49-42gf) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### Release Notes

<details>
<summary>grpc/grpc-go (google.golang.org/grpc)</summary>

### [`v1.82.1`](https://github.com/grpc/grpc-go/releases/tag/v1.82.1): Release 1.82.1

[Compare Source](grpc/grpc-go@v1.82.0...v1.82.1)

### Security

- server: Stop reading from the connection when flooded by HTTP/2 frames.  The default value for this limit is 100 frames, excluding DATA and HEADERS, and may be changed by setting environment variable `GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT`.
- xds/rbac: Support `Metadata` and `RequestedServerName` permissions matcher fields.  If present in a DENY rule, previously these would be ignored and fail-open.
- xds/rbac: Fix panic when parsing unsupported fields in `NotRule`/`NotId` permissions.
- xds/rbac: Support the deprecated `source_ip` principal identifier by treating it as equivalent to `direct_remote_ip`.

### [`v1.82.0`](https://github.com/grpc/grpc-go/releases/tag/v1.82.0): Release 1.82.0

[Compare Source](grpc/grpc-go@v1.81.1...v1.82.0)

### Behavior Changes

- server: Remove support for `GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING` environment varibale. Strict incoming RPC path validation (which has been the default since `v1.79.3`) can no longer be disabled. ([#&#8203;9112](grpc/grpc-go#9112))
- transport: Add environment variable to change the default max header list size from `16MB` to `8KB`. This may be enabled by setting `GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE=true`. This will be enabled by default in a subsequent release. ([#&#8203;9019](grpc/grpc-go#9019))
- balancer: Load Balancing policy registry is now case-sensitive.  Set `GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES=false` (and file an issue) to revert to case-insensitive behavior. ([#&#8203;9017](grpc/grpc-go#9017))

### New Features

- experimental/stats: Expose a new API, `NewContextWithLabelCallback`, to register a callback that is invoked when telemetry labels are added. ([#&#8203;8877](grpc/grpc-go#8877))
  - Special Thanks: [@&#8203;seth-epps](https://github.com/seth-epps)
- client: Return a portion of the response body in the error message, when the client receives an unexpected non-gRPC HTTP response, to make debugging easier. ([#&#8203;8929](grpc/grpc-go#8929))
  - Special Thanks: [@&#8203;chengxilo](https://github.com/chengxilo)
- server: Add environment variable `GRPC_GO_SERVER_GOROUTINE_LABELS` that controls setting `runtime/pprof.Labels` on goroutines spawned by the server. Set `GRPC_GO_SERVER_GOROUTINE_LABELS=grpc.method=true` to add the `grpc.method` label on goroutines spawned to handle incoming requests. ([#&#8203;9082](grpc/grpc-go#9082))
  - Special Thanks: [@&#8203;dfinkel](https://github.com/dfinkel)

### Bug Fixes

- xds/server: Fix a memory leak of HTTP filter instances occurring when route configurations are updated in-place during a Route Discovery Service (RDS) update. ([#&#8203;9138](grpc/grpc-go#9138))
- grpc: In the deprecated `gzip` Compressor (used via the deprecated `WithCompressor` dial option), enforce the `MaxRecvMsgSize` limit on the decompressed message buffer, preventing excessive memory allocation from highly compressed payloads. ([#&#8203;9114](grpc/grpc-go#9114))
  - Special Thanks: [@&#8203;evilgensec](https://github.com/evilgensec)
- stats/opentelemetry: Record retry attempts, `grpc.previous-rpc-attempts`, at the call level and not the attempt level. ([#&#8203;8923](grpc/grpc-go#8923))
- encoding: Ensure `Close()` is always called on readers returned from `Compressor.Decompress` if possible. ([#&#8203;9135](grpc/grpc-go#9135))
- channelz: Fix the `LastMessageSentTimestamp` and `LastMessageReceivedTimestamp` fields in `SocketMetrics` to ensure they contain correct timestamp values. ([#&#8203;9109](grpc/grpc-go#9109))

### [`v1.81.1`](https://github.com/grpc/grpc-go/releases/tag/v1.81.1): Release 1.81.1

[Compare Source](grpc/grpc-go@v1.81.0...v1.81.1)

### Security

- xds/rbac: Fix a potential authorization bypass caused by incorrectly falling through URI/DNS SANs to Subject Distinguished Name (DN) when matching the authenticated principal name. With this fix, only the first non-empty identity source will be used, as per [gRFC A41](https://github.com/grpc/proposal/blob/master/A41-xds-rbac.md). ([#&#8203;9111](grpc/grpc-go#9111))
  - Special Thanks: [@&#8203;al4an444](https://github.com/al4an444)

### Bug Fixes

- otel: Segregate client and server RPC information used for metrics and traces, to avoid one overwriting the other. ([#&#8203;9081](grpc/grpc-go#9081))

### [`v1.81.0`](https://github.com/grpc/grpc-go/releases/tag/v1.81.0): Release 1.81.0

[Compare Source](grpc/grpc-go@v1.80.0...v1.81.0)

### Behavior Changes

- balancer/rls: Switch gauge metrics to asynchronous emission (once per collection cycle) to reduce telemetry noise and align with other gRPC language implementations. ([#&#8203;8808](grpc/grpc-go#8808))

### Dependencies

- Minimum supported Go version is now 1.25. ([#&#8203;8969](grpc/grpc-go#8969))

### Bug Fixes

- xds: Use the leaf cluster's security config for the TLS handshake instead of the aggregate cluster's config. ([#&#8203;8956](grpc/grpc-go#8956))
- transport: Send a `RST_STREAM` when receiving an `END_STREAM` when the stream is not already half-closed. ([#&#8203;8832](grpc/grpc-go#8832))
- xds: Fix ADS resource name validation to prevent a panic. ([#&#8203;8970](grpc/grpc-go#8970))

### New Features

- grpc/stats: Add support for custom labels in per-call metrics ([gRFC A108](https://github.com/grpc/proposal/blob/master/A108-otel-custom-per-call-label.md)). ([#&#8203;9008](grpc/grpc-go#9008))
- xds: Add support for Server Name Indication (SNI) and SAN validation ([gRFC A101](https://github.com/grpc/proposal/blob/master/A101-SNI-setting-and-SNI-SAN-validation.md)). Disabled by default. To enable, set `GRPC_EXPERIMENTAL_XDS_SNI=true` environment variable. ([#&#8203;9016](grpc/grpc-go#9016))
- xds: Add support to control which fields get propagated from ORCA backend metric reports to LRS load reports ([gRFC A85](https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md)). Disabled by default. To enable, set `GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION=true`. ([#&#8203;9005](grpc/grpc-go#9005))
- xds: Add metrics to track xDS client connectivity and cached resource state ([gRFC A78](https://github.com/grpc/proposal/blob/master/A78-grpc-metrics-wrr-pf-xds.md)). ([#&#8203;8807](grpc/grpc-go#8807))
- stats/otel: Enhance `grpc.subchannel.disconnections` metric by adding disconnection reason to the `grpc.disconnect_error` label ([gRFC A94](https://github.com/grpc/proposal/blob/master/A94-subchannel-otel-metrics.md)). This provides granular insights into why subchannels are closing. ([#&#8203;8973](grpc/grpc-go#8973))
- mem: Add `mem.Buffer.Slice()` API to slice the buffer like a slice. ([#&#8203;8977](grpc/grpc-go#8977))
  - Special Thanks: [@&#8203;ash2k](https://github.com/ash2k)

### Performance Improvements

- alts: Pool read buffers to lower memory utilization when sockets are unreadable. ([#&#8203;8964](grpc/grpc-go#8964))
- transport: Pool HTTP/2 framer read buffers to reduce idle memory consumption. Currently limited to Linux for ALTS and non-encrypted transports (TCP, Unix). To disable, set `GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING=false` and report any issues. ([#&#8203;9032](grpc/grpc-go#9032))

### [`v1.80.0`](https://github.com/grpc/grpc-go/releases/tag/v1.80.0): Release 1.80.0

[Compare Source](grpc/grpc-go@v1.79.3...v1.80.0)

### Behavior Changes

- balancer: log a warning if a balancer is registered with uppercase letters, as balancer names should be lowercase. In a future release, balancer names will be treated as case-insensitive; see [#&#8203;5288](grpc/grpc-go#5288) for details. ([#&#8203;8837](grpc/grpc-go#8837))
- xds: update resource error handling and re-resolution logic ([#&#8203;8907](grpc/grpc-go#8907))
  - Re-resolve all `LOGICAL_DNS` clusters simultaneously when re-resolution is requested.
  - Fail all in-flight RPCs immediately upon receipt of listener or route resource errors, instead of allowing them to complete.

### Bug Fixes

- xds: support the LB policy configured in `LOGICAL_DNS` cluster resources instead of defaulting to `pick_first`. ([#&#8203;8733](grpc/grpc-go#8733))
- credentials/tls: perform per-RPC authority validation against the leaf certificate instead of the entire peer certificate chain. ([#&#8203;8831](grpc/grpc-go#8831))
- xds: enabling A76 ring hash endpoint keys no longer causes EDS resources with invalid proxy metadata to be NACKed when HTTP CONNECT (gRFC A86) is disabled. ([#&#8203;8875](grpc/grpc-go#8875))
- xds: validate that the sum of endpoint weights in a locality does not exceed the maximum `uint32` value. ([#&#8203;8899](grpc/grpc-go#8899))
  - Special Thanks: [@&#8203;RAVEYUS](https://github.com/RAVEYUS)
- xds: fix incorrect proto field access in the weighted round robin (WRR) configuration where `blackout_period` was used instead of `weight_expiration_period`. ([#&#8203;8915](grpc/grpc-go#8915))
  - Special Thanks: [@&#8203;gregbarasch](https://github.com/gregbarasch)
- xds/rbac: handle addresses with ports in IP matchers. ([#&#8203;8990](grpc/grpc-go#8990))

### New Features

- ringhash: enable gRFC A76 (endpoint hash keys and request hash headers) by default. ([#&#8203;8922](grpc/grpc-go#8922))

### Performance Improvements

- credentials/alts: pool write buffers to reduce memory allocations and usage. ([#&#8203;8919](grpc/grpc-go#8919))
- grpc: enable the use of pooled write buffers for buffering HTTP/2 frame writes by default. This reduces memory usage when connections are idle. Use the [WithSharedWriteBuffer](https://pkg.go.dev/google.golang.org/grpc#WithSharedWriteBuffer) dial option or the [SharedWriteBuffer](https://pkg.go.dev/google.golang.org/grpc#SharedWriteBuffer) server option to disable this feature. ([#&#8203;8957](grpc/grpc-go#8957))
- xds/priority: stop caching child LB policies removed from the configuration. This will help reduce memory and cpu usage when localities are constantly switching between priorities. ([#&#8203;8997](grpc/grpc-go#8997))
- mem: add a faster tiered buffer pool; use the experimental [mem.NewBinaryTieredBufferPool](https://pkg.go.dev/google.golang.org/grpc/mem@master#NewBinaryTieredBufferPool) function to create such pools. ([#&#8203;8775](grpc/grpc-go#8775))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNzIuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI3Mi4wIiwidGFyZ2V0QnJhbmNoIjoidjE2LjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13580
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
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.

5 participants