-
Notifications
You must be signed in to change notification settings - Fork 27
RFC 008: Server compression preference #405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
62de975
d3e9fb3
386b1f9
bb11cb5
a56f127
536d985
a081cea
1bee82a
b415fb7
e542fd7
e4c94ce
31e708f
797ef81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| --- | ||
| title: "008: Server compression preference" | ||
| --- | ||
|
|
||
| This RFC proposes amending the Connect protocol to have servers define the | ||
| preference for a compression algorithm among the supported set as opposed to | ||
| the client. This allows improving compression in scenarios where the client's | ||
| ordering cannot be changed, like the browser, and aligns with the commonly | ||
| accepted behavior of servers like Envoy and NGINX. | ||
|
|
||
| The proposed diff to the protocol specification is in [PR 322][pr322]. This | ||
| document focuses on the rationale for the change and the anticipated end user | ||
| impact. | ||
|
|
||
| ## Current behavior | ||
|
|
||
| The compression algorithm to use for a request is determined by two factors: | ||
|
|
||
| - The list of supported compression methods configured on the server | ||
| - The list of supported compression methods in the client's `Accept-Encoding` header, e.g., `gzip, br, zstd` | ||
|
|
||
| Currently, it is the order in the `Accept-Encoding` header that determines which | ||
| algorithm to prefer. The server chooses the first compression method that it supports. | ||
|
Comment on lines
+19
to
+23
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In connect-go the response compression is chosen to match the request: https://github.com/connectrpc/connect-go/blob/51112608939254772c8e67577eb5b353741aaa7e/protocol.go#L308-L311 This seems to not be defined in the Spec.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing this out! It seems most intuitive to match the request when the request is compressed. Connect-Py currently does not, since I think I was reading the spec closely when implementing that. This seems like the right time to consolidate this behavior. I have added a note to use the request compression when provided. |
||
|
|
||
| Because common browsers always send `gzip, deflate, br, zstd`, and because all current Connect server implementations support `gzip` by default, it is currently impossible for | ||
| connect-web users to use the more modern and efficient `br` and `zstd` algorithms unless a Connect server disables support for `gzip`. | ||
|
|
||
| ## Proposed behavior | ||
|
|
||
| We propose changing the algorithm so that servers are configured with an ordered list of compression methods, | ||
| and the first matching method present in the `Accept-Encoding` header is selected. | ||
|
anuraaga marked this conversation as resolved.
Outdated
|
||
|
|
||
| For example, given `Accept-Encoding: gzip, br, zstd` | ||
|
|
||
| - If the server is configured with `gzip, br, zstd`, then `gzip` is selected. | ||
| - If the server is configured with `br, zstd, gzip`, then `br` is selected. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the
anuraaga marked this conversation as resolved.
Outdated
|
||
|
|
||
| Moving preference to the server will allow preferring the more efficient algorithms, finally | ||
| unlocking them for connect-web. Servers like Envoy and NGINX behave in the same way for the | ||
| same reason. | ||
|
|
||
| While `br` and `zstd` have come a long way and commonly have similar CPU and RAM usage to | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's something to mention here in regard to Brotli. The official reference library defaults to a compression level of 11 (out of 11). That's level uses A LOT of CPU. And so little-by-little languages are starting to switch the default, but it seems like a lot have not gotten the memo:
And with load balancers, almost none of them use the high default:
I don't think there's anything to do here immediately, but I wanted this to be known about. Defaults are super important for things like this. I suspect documentation of the server compression priority for each language is where this is useful. From my experiments, brotli compression at level 11 uses so much CPU that the expected RPS for a typical app service will plummet.
when configured appropriately.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup we aligned with Envoy in connect-py I'm not going to complicate the prose for that here though. If we want to add compression levels to the spec, probably another PR that doesn't necessarily need an RFC (maybe) |
||
| `gzip` now, it can't be confirmed all workloads will see no regression from a change from | ||
| `gzip` to e.g., `br`. In an abundance of caution, if this RFC is approved, then this new behavior will only be introduced in Connect implementations as part of a major version. It is planned to be introduced to Connect-Go in v2, Connect-Py before v1, and Connect-ES | ||
| in v3. | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest that we clarify that this change applies not only to unary RPCs, but also to streaming RPCs and unary GET, and that it applies to all three protocols if an implementation supports them, not only to the Connect protocol.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point - I have added a note about it in 31e708f |
||
| [pr322]: https://github.com/connectrpc/connectrpc.com/pull/322 | ||
Uh oh!
There was an error while loading. Please reload this page.