Project: gRPC (Orchestration & Management / Remote Procedure Call)
File: compression_cookbook.md

This document describes compression as implemented by the gRPC C core. See [the full compression specification](compression.md) for details. Wrapped languages developers, for the purposes of supporting compression by interacting with the C core. Be able to set compression at , and level. In principle this API should be based on compression levels as opposed to algorithms. See the discussion . Have unit tests covering [the cases from the spec](https://github.com/grpc/grpc/blob/master/doc/compression.md#test-cases). Interop tests implemented and passing on Jenkins. The two relevant interop test cases are and . The following flowcharts depict the evolution of a message, both incoming and outgoing, irrespective of the client/server character of the call. Aspects still not symmetric between clients and servers (e.g. the [use of compression levels](https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-levels-and-algorithms)) are explicitly marked. The in-detail textual description for the different scenarios is described in subsequent sections. As mentioned in [the relevant discussion on the spec document](https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-levels-and-algorithms), compression levels are the primary mechanism for compression selection _at the server side_. In the future, it'll also be at the client side. The use of levels abstracts away the intricacies of selecting a concrete algorithm supported by a peer, on top of removing the burden of choice from the developer. As of this writing (Q2 2016), clients can only specify compression algorithms. Clients will support levels as soon as an automatic retry/negotiation mechanism is in place. Compression may be configured at channel creation. This is a convenience to avoid having to repeatedly configure compression for every call. Note that any compression setting on individual or overrides channel settings. The following aspects can be configured at channel-creation time via channel arguments: Use the channel argument key `GRPCCOMPRESSIONCHANNELENABLEDALGORITHMS_BITSET` (from ), takes a 32 bit bitset value. A set bit means the algorithm with that enum value according to `grpccompressionalgorithm` is enabled. For example, `GRPCCOMPRESSGZIP` currently has a numeric value of

To enable/disable GZIP for a channel, one would set/clear the 3rd LSB (eg, 0b100 = 0x4). Note that setting/clearing 0th position, that corresponding to `GRPCCOMPRESSNONE`, has no effect, as no-compression (a.k.a. identity) is always supported. Incoming messages compressed (ie, encoded) with a disabled algorithm will result in the call being closed with `GRPCSTATUSUNIMPLEMENTED`. (currently, Q2 2016, only applicable for server side channels. It's ignored for clients.) Use the channel argument key `GRPCCOMPRESSIONCHANNELDEFAULTLEVEL` (from ), valued by an integer corresponding to a value from the `grpccompressionlevel` enum. Use the channel argument key `GRPCCOMPRESSIONCHANNELDEFAULTALGORITHM` (from ), valued by an integer corresponding to a value from the `grpccompressionlevel` enum. The server requests a compression level via initial metadata. The `sendinitialmetadata` `grpcop` contains a `maybecompression_level` field with two fields, `isset` and `compressionlevel`. The former must be set when actively choosing a level to disambiguate the default value of zero (no compression) from the proactive selection of no compression. The core will receive the request for the compression level and automatically choose a compression algorithm based on its knowledge about the peer (communicated by the client via the `grpc-accept-encoding` header. Note that the absence of this header means no compression is supported by the client/peer). Server should avoid setting the compression algorithm directly. Prefer setting compression levels unless there's a very compelling reason to choose specific algorithms (benchmarking, testing). Selection of concrete compression algorithms is performed by adding a `(GRPCCOMPRESSREQUESTALGORITHMKEY, <algorithm-name>)` key-value pair to the initial metadata, where `GRPCCOMPRESSREQUESTALGORITHMKEY` is defined in ), and `<algorithm-name>` is the human readable name of the algorithm as given in for `Message-Encoding` (e.g. gzip, identity, etc.). See for the mapping between the `grpccompressionalgorithm` enum values and their textual representation. To disable compression for a specific message, the `flags` field of `grpc_op` instances of type `GRPCOPSENDMESSAGE` must have its `GRPCWRITENOCOMPRESS` bit set. Refer to ),