transport: skip HPACK indexing for per-RPC-unique request headers - #9377
Open
doroshenkosa wants to merge 1 commit into
Open
transport: skip HPACK indexing for per-RPC-unique request headers#9377doroshenkosa wants to merge 1 commit into
doroshenkosa wants to merge 1 commit into
Conversation
|
|
doroshenkosa
force-pushed
the
transport-hpack-never-index-unique-headers
branch
from
August 25, 2026 20:14
18afaca to
9a2d432
Compare
…ader
The client transport shares a single HPACK encoder across every RPC on a
connection, so the encoder's dynamic table state persists between requests.
grpc-timeout carries the remaining time until the deadline, so its value is
effectively unique on every RPC.
Adding such a value to the HPACK dynamic table never yields a compression hit on
a later request: the value is different every time. It only costs a map insert
per RPC and, once the 4KB table fills, evicts genuinely reusable entries such as
content-type and :authority, which then have to be re-added. Marking the field
as sensitive keeps the encoder from indexing it, which both lowers CPU spent in
the encoder and improves the compression ratio of the surrounding, reusable
fields.
An isolated encode benchmark (single reused encoder, fresh grpc-timeout per
iteration, Apple M4) shows the encode path getting faster once grpc-timeout is
no longer indexed:
metadata fields indexed never-indexed delta
0 ~380 ns/op ~294 ns/op -23%
4 ~498 ns/op ~416 ns/op -16%
12 ~765 ns/op ~697 ns/op -9%
The sensitive value is still Huffman-encoded, so the bytes on the wire for the
value itself are unchanged; only the dynamic-table entry is dropped. The
"never indexed" literal representation is standard HPACK (RFC 7541 6.2.3) and is
decoded by any compliant peer.
doroshenkosa
force-pushed
the
transport-hpack-never-index-unique-headers
branch
from
August 25, 2026 20:27
9a2d432 to
6f166ea
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #9377 +/- ##
==========================================
+ Coverage 87.47% 87.52% +0.04%
==========================================
Files 425 425
Lines 30303 30303
==========================================
+ Hits 26508 26522 +14
+ Misses 3794 3780 -14
Partials 1 1
🚀 New features to boost your workflow:
|
Member
|
Hey @doroshenkosa , thank you for making this change! I am discussing this internally with the other maintainers to align on the best approach, and I will get back to you soon. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The client transport shares a single HPACK encoder across every RPC on a
connection, so the encoder's dynamic table state persists between requests.
grpc-timeout carries the remaining time until the deadline, so its value is
effectively unique on every RPC.
Adding such a value to the HPACK dynamic table never yields a compression hit on
a later request: the value is different every time. It only costs a map insert
per RPC and, once the 4KB table fills, evicts genuinely reusable entries such as
content-type and :authority, which then have to be re-added. Marking the field
as sensitive keeps the encoder from indexing it, which lowers CPU spent in the
encoder and keeps the surrounding reusable fields from being evicted.
An isolated encode benchmark (single reused encoder, fresh grpc-timeout per
iteration, Apple M4) shows the encode path getting faster once grpc-timeout is
no longer indexed:
The sensitive value is still Huffman-encoded, so the bytes on the wire for the
value itself are unchanged; only the dynamic-table entry is dropped. The
"never indexed" literal representation is standard HPACK (RFC 7541 §6.2.3) and
is decoded by any compliant peer.
RELEASE NOTES:
header to the HPACK dynamic table