Repository navigation
Conversation
Signed-off-by: Kyle Eckhart <kgeckhart@users.noreply.github.com>
bwplotka
left a comment
There was a problem hiding this comment.
Nice! Some suggestions, otherwise looks great.
Thanks!
| * `gzip`: MUST follow [RFC 1952](https://www.rfc-editor.org/rfc/rfc1952.html). | ||
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). | ||
|
|
||
| Senders and Receivers MUST support `snappy`. Receivers SHOULD support `gzip` and `zstd`. `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. |
There was a problem hiding this comment.
Since gzip and zstd are SHOULD for Receivers and 415 retry is MAY for Senders, Senders SHOULD still default to snappy unless configured otherwise or advertised via Accept-Encoding so 2.x Senders and snappy-only Receivers interoperate out of the box. Also, MUST only be used leaves it ambiguous whether HTTP decompression middlewares running before Content-Type parsing must reject prometheus.WriteRequest compressed with gzip or zstd:
| Senders and Receivers MUST support `snappy`. Receivers SHOULD support `gzip` and `zstd`. `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. | |
| Senders and Receivers MUST support `snappy`. Receivers SHOULD support `gzip` and `zstd`. Senders MAY support `gzip` and `zstd`, and SHOULD use `snappy` by default unless configured otherwise or advertised by the Receiver via `Accept-Encoding`. Senders MUST NOT use `gzip` or `zstd` with `prometheus.WriteRequest`, and Receivers MAY reject such requests with `415 HTTP Unsupported Media Type`. |
There was a problem hiding this comment.
I took most of this. I made it “MAY use” instead of “MAY support”, and turned the prometheus.WriteRequest MUST NOT into a scope sentence (gzip and zstd MUST only be used with io.prometheus.write.v2.Request). I left out “Receivers MAY reject with 415” since the 415 section already covers it.
|
|
||
| Senders and Receivers MUST support `snappy`. Receivers SHOULD support `gzip` and `zstd`. `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. | ||
|
|
||
| Receivers MAY include the `Accept-Encoding` response header on 2xx responses to advertise supported `Content-Encoding` values, as defined in [RFC 7694](https://www.rfc-editor.org/rfc/rfc7694.html). Senders MAY use it to choose a supported encoding for subsequent requests. |
There was a problem hiding this comment.
If a Receiver pool sits behind an L7 load balancer during a rolling update or rollback, upgrading from a 2xx Accept-Encoding header without 415 retry support will drop batches when subsequent requests hit snappy-only replicas, or flip-flop across replicas. Also, RFC 9110 obsoleted RFC 7694 and folded response Accept-Encoding directly into Section 12.5.3:
| Receivers MAY include the `Accept-Encoding` response header on 2xx responses to advertise supported `Content-Encoding` values, as defined in [RFC 7694](https://www.rfc-editor.org/rfc/rfc7694.html). Senders MAY use it to choose a supported encoding for subsequent requests. | |
| Receivers MAY include the `Accept-Encoding` response header on 2xx responses to advertise supported `Content-Encoding` values for that request, as defined in [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding). Senders using `io.prometheus.write.v2.Request` MAY use it to choose an allowed encoding for subsequent requests, in which case they MUST fall back to `snappy` and retry on `415 HTTP Unsupported Media Type` and SHOULD avoid immediately re-upgrading across load-balanced Receiver replicas. |
There was a problem hiding this comment.
I took this and moved it into the Content-Encoding section so the Accept-Encoding rules live in one place. I made the fallback “retry once with snappy“, and skipped it when the 415 has Accept but no Accept-Encoding. I dropped the re-upgrade SHOULD because I couldn’t figure out how to test “immediately”. Happy to add it back if you have wording in mind.
| #### Unsupported Request Content | ||
|
|
||
| Receivers MUST return [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) status code if they don't support a given content type or encoding provided by Senders. When returning `415 HTTP Unsupported Media Type`, Receivers SHOULD include the `Accept` (listing supported `Content-Type` values, including supported `;proto=` and `;mode=` parameters) and `Accept-Encoding` (listing supported `Content-Encoding` values) response headers as defined in [RFC 7694](https://www.rfc-editor.org/rfc/rfc7694.html) so Senders can determine what the Receiver supports without guessing. | ||
| Receivers MUST return [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) status code if they don't support a given content type or encoding provided by Senders. When returning `415 HTTP Unsupported Media Type`, Receivers SHOULD include the `Accept` response header (listing supported `Content-Type` values, including supported `;proto=` and `;mode=` parameters) so Senders can determine what the Receiver supports without guessing. If the 415 is due to an unsupported `Content-Encoding`, Receivers SHOULD also include the `Accept-Encoding` response header listing supported `Content-Encoding` values. Otherwise, in a 415 response, Receivers MUST NOT include `Accept-Encoding`, as defined in [RFC 7694](https://www.rfc-editor.org/rfc/rfc7694.html). |
There was a problem hiding this comment.
Keeping Accept as an unconditional SHOULD on all 415 responses means decompression middlewares like SnappyDecodeMiddleware or reverse proxies violate SHOULD when rejecting Content-Encoding before the inner handler knows accepted ;proto= and ;mode= values. Maybe scope Accept to Content-Type rejections per RFC 9110 Section 15.5.16 and link RFC 9110 Section 12.5.3 instead of obsoleted RFC 7694:
| Receivers MUST return [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) status code if they don't support a given content type or encoding provided by Senders. When returning `415 HTTP Unsupported Media Type`, Receivers SHOULD include the `Accept` response header (listing supported `Content-Type` values, including supported `;proto=` and `;mode=` parameters) so Senders can determine what the Receiver supports without guessing. If the 415 is due to an unsupported `Content-Encoding`, Receivers SHOULD also include the `Accept-Encoding` response header listing supported `Content-Encoding` values. Otherwise, in a 415 response, Receivers MUST NOT include `Accept-Encoding`, as defined in [RFC 7694](https://www.rfc-editor.org/rfc/rfc7694.html). | |
| Receivers MUST return [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) status code if they don't support a given content type or encoding provided by Senders. If the 415 is due to an unsupported `Content-Type`, Receivers SHOULD include the [`Accept`](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept) response header listing supported `Content-Type` values, including supported `;proto=` and `;mode=` parameters, so Senders can determine what the Receiver supports without guessing. If the 415 is due to an unsupported `Content-Encoding`, Receivers SHOULD include the [`Accept-Encoding`](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding) response header listing supported `Content-Encoding` values. Receivers that return 415 for reasons unrelated to `Content-Encoding` MUST NOT include `Accept-Encoding`, as defined in [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding). |
There was a problem hiding this comment.
Took the Content-Type half as is. I moved the Accept-Encoding half up next to the 2xx rule and linked to it from here.
Proposal is completely out of sync at this point. However it tried to explain history of certain changes and its motivation. Perhaps we close the proposal and write a biggy blog post for this. Not sure yet. Fine to skip for now. |
Signed-off-by: Kyle Eckhart <kgeckhart@users.noreply.github.com>
|
|
||
| * `snappy`: [Google’s Snappy](https://github.com/google/snappy). The [block format](https://github.com/google/snappy/blob/2c94e11145f0b7b184b831577c93e5a41c4c0346/format_description.txt) MUST be used -- [the framed format](https://github.com/google/snappy/blob/2c94e11145f0b7b184b831577c93e5a41c4c0346/framing_format.txt) MUST NOT be used. | ||
| * `gzip`: MUST follow [RFC 1952](https://www.rfc-editor.org/rfc/rfc1952.html). | ||
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). |
There was a problem hiding this comment.
Neither RFC 8878 nor RFC 9659 forbids Zstandard dictionaries on zstd content coding, and RW 2.0 has no dictionary negotiation yet. Worth ruling them out explicitly like Snappy's framed format above:
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). | |
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). Dictionaries MUST NOT be used. |
| * `gzip`: MUST follow [RFC 1952](https://www.rfc-editor.org/rfc/rfc1952.html). | ||
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). | ||
|
|
||
| `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. `prometheus.WriteRequest` is unchanged from [1.0](./remote_write_spec.md), `snappy` only. |
There was a problem hiding this comment.
Since #unsupported-request-content is a MUST, passive MUST only be used here implies dual-version Receivers have to reject prometheus.WriteRequest compressed with gzip or zstd, which breaks HTTP decompression middlewares in client_golang or reverse proxies that decode Content-Encoding before checking Content-Type. Keeping MUST NOT on Senders and MAY on Receivers lets both middleware-first and Content-Type-first Receivers pass compliance:
| `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. `prometheus.WriteRequest` is unchanged from [1.0](./remote_write_spec.md), `snappy` only. | |
| Senders MUST NOT use `gzip` or `zstd` with `prometheus.WriteRequest`, which remains `snappy` only as in [1.0](./remote_write_spec.md). Receivers MAY reject `prometheus.WriteRequest` compressed with `gzip` or `zstd` with [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type). |
|
|
||
| Senders and Receivers MUST support `snappy`. Receivers SHOULD support `gzip` and `zstd`. Senders MAY use `gzip` or `zstd`, and SHOULD use `snappy` unless configured otherwise or the Receiver advertised the encoding with `Accept-Encoding`. | ||
|
|
||
| Receivers advertise supported `Content-Encoding` values with the [`Accept-Encoding`](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding) response header, which applies to the request it answers. Receivers MAY send it on 2xx responses. On a [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) they SHOULD send it when an unsupported `Content-Encoding` is the cause, and MUST NOT send it otherwise. A Sender that chose its encoding from a 2xx `Accept-Encoding` MUST retry once with `snappy` when it gets a 415, unless the 415 carries `Accept` and no `Accept-Encoding`. |
There was a problem hiding this comment.
MUST retry once with snappy only retries that single batch and leaves gzip or zstd active for subsequent requests after a Receiver rollback. Also, phrasing the re-upgrade guard as a cooldown makes it easy to test in prometheus/compliance with back-to-back scrapes right after a 415 fallback:
| Receivers advertise supported `Content-Encoding` values with the [`Accept-Encoding`](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding) response header, which applies to the request it answers. Receivers MAY send it on 2xx responses. On a [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) they SHOULD send it when an unsupported `Content-Encoding` is the cause, and MUST NOT send it otherwise. A Sender that chose its encoding from a 2xx `Accept-Encoding` MUST retry once with `snappy` when it gets a 415, unless the 415 carries `Accept` and no `Accept-Encoding`. | |
| Receivers advertise supported `Content-Encoding` values with the [`Accept-Encoding`](https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding) response header, which applies to the request it answers. Receivers MAY send it on 2xx responses. On a [415 HTTP Unsupported Media Type](https://www.rfc-editor.org/rfc/rfc9110.html#name-415-unsupported-media-type) they SHOULD send it when an unsupported `Content-Encoding` is the cause, and MUST NOT send it otherwise. A Sender that switched to `gzip` or `zstd` from a 2xx `Accept-Encoding` MUST revert to `snappy` for subsequent requests and retry the failed request once with `snappy` when it gets a 415, unless the 415 carries `Accept` and no `Accept-Encoding`. After reverting on a 415, the Sender SHOULD wait for a cooldown period before switching away from `snappy` via `Accept-Encoding` again. |
| * `gzip`: MUST follow [RFC 1952](https://www.rfc-editor.org/rfc/rfc1952.html). | ||
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). | ||
|
|
||
| `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. `prometheus.WriteRequest` is unchanged from [1.0](./remote_write_spec.md), `snappy` only. |
There was a problem hiding this comment.
" snappy only." is weird. Did you forget to finish some sentence?
| * `gzip`: MUST follow [RFC 1952](https://www.rfc-editor.org/rfc/rfc1952.html). | ||
| * `zstd`: MUST follow [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878.html) and [RFC 9659](https://www.rfc-editor.org/rfc/rfc9659.html). | ||
|
|
||
| `gzip` and `zstd` MUST only be used with `io.prometheus.write.v2.Request`. `prometheus.WriteRequest` is unchanged from [1.0](./remote_write_spec.md), `snappy` only. |
There was a problem hiding this comment.
Let's also be specific (sender/receiver). Mention e.g. "Sender MUST NOT".
Optionally allow
gzipandzstdcompression while Senders and Receivers still MUST supportsnappy.RW2 with snappy sends roughly 1.7x the bytes of OTLP with gzip. gzip or zstd closes that gap. On the Receiver side, zstd decodes about 9% slower than snappy, and still well under OTLP with gzip.
All numbers are for 10000 samples.
Size
Encode
Decode
Medians of 6 runs from @bwplotka's October 2026 metrics-streaming benchmarks (encode, decode),
vtprotobuf, zstd atSpeedFastest, gzip atDefaultCompression.The 2.0 proposal held off on new compressions over receiver-side CPU cost. Keeping
gzipandzstda SHOULD for Receivers leaves that choice with them.Related to: prometheus/prometheus#13366