1# gRPC (Core) Compression Cookbook 2 3## Introduction 4 5This document describes compression as implemented by the gRPC C core. See [the 6full compression specification](compression.md) for details. 7 8### Intended Audience 9 10Wrapped languages developers, for the purposes of supporting compression by 11interacting with the C core. 12 13## Criteria for GA readiness 14 151. Be able to set compression at [channel](#per-channel-settings), 16 [call](#per-call-settings) and [message](#per-message-settings) level. 17 In principle this API should be based on _compression levels_ as opposed to 18 algorithms. See the discussion [below](#level-vs-algorithms). 191. Have unit tests covering [the cases from the 20 spec](https://github.com/grpc/grpc/blob/master/doc/compression.md#test-cases). 211. Interop tests implemented and passing on Jenkins. The two relevant interop 22 test cases are 23 [large_compressed_unary](https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#large_compressed_unary) 24 and 25 [server_compressed_streaming](https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#server_compressed_streaming). 26 27## Summary Flowcharts 28 29The following flowcharts depict the evolution of a message, both _incoming_ and 30_outgoing_, irrespective of the client/server character of the call. Aspects 31still not symmetric between clients and servers (e.g. the [use of compression 32levels](https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-levels-and-algorithms)) 33are explicitly marked. The in-detail textual description for the different 34scenarios is described in subsequent sections. 35 36## Incoming Messages 37 38![image](images/compression_cookbook_incoming.png) 39 40## Outgoing Messages 41 42![image](images/compression_cookbook_outgoing.png) 43 44## Levels vs Algorithms 45 46As mentioned in [the relevant discussion on the spec 47document](https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-levels-and-algorithms), 48compression _levels_ are the primary mechanism for compression selection _at the 49server side_. In the future, it'll also be at the client side. The use of levels 50abstracts away the intricacies of selecting a concrete algorithm supported by a 51peer, on top of removing the burden of choice from the developer. 52As of this writing (Q2 2016), clients can only specify compression _algorithms_. 53Clients will support levels as soon as an automatic retry/negotiation mechanism 54is in place. 55 56## Per Channel Settings 57 58Compression may be configured at channel creation. This is a convenience to 59avoid having to repeatedly configure compression for every call. Note that any 60compression setting on individual [calls](#per-call-settings) or 61[messages](#per-message-settings) overrides channel settings. 62 63The following aspects can be configured at channel-creation time via channel arguments: 64 65#### Disable Compression _Algorithms_ 66 67Use the channel argument key 68`GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET` (from 69[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 70takes a 32 bit bitset value. A set bit means the algorithm with that enum value 71according to `grpc_compression_algorithm` is _enabled_. 72For example, `GRPC_COMPRESS_GZIP` currently has a numeric value of 2. To 73enable/disable GZIP for a channel, one would set/clear the 3rd LSB (eg, 0b100 = 740x4). Note that setting/clearing 0th position, that corresponding to 75`GRPC_COMPRESS_NONE`, has no effect, as no-compression (a.k.a. _identity_) is 76always supported. 77Incoming messages compressed (ie, encoded) with a disabled algorithm will result 78in the call being closed with `GRPC_STATUS_UNIMPLEMENTED`. 79 80#### Default Compression _Level_ 81 82**(currently, Q2 2016, only applicable for server side channels. It's ignored 83for clients.)** 84Use the channel argument key `GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL` (from 85[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 86valued by an integer corresponding to a value from the `grpc_compression_level` 87enum. 88 89#### Default Compression _Algorithm_ 90 91Use the channel argument key `GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM` (from 92[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 93valued by an integer corresponding to a value from the `grpc_compression_level` 94enum. 95 96## Per Call Settings 97 98### Compression **Level** in Call Responses 99 100The server requests a compression level via initial metadata. The 101`send_initial_metadata` `grpc_op` contains a `maybe_compression_level` field 102with two fields, `is_set` and `compression_level`. The former must be set when 103actively choosing a level to disambiguate the default value of zero (no 104compression) from the proactive selection of no compression. 105 106The core will receive the request for the compression level and automatically 107choose a compression algorithm based on its knowledge about the peer 108(communicated by the client via the `grpc-accept-encoding` header. Note that the 109absence of this header means no compression is supported by the client/peer). 110 111### Compression **Algorithm** in Call Responses 112 113**Server should avoid setting the compression algorithm directly**. Prefer 114setting compression levels unless there's a _very_ compelling reason to choose 115specific algorithms (benchmarking, testing). 116 117Selection of concrete compression algorithms is performed by adding a 118`(GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, <algorithm-name>)` key-value pair to the 119initial metadata, where `GRPC_COMPRESS_REQUEST_ALGORITHM_KEY` is defined in 120[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 121and `<algorithm-name>` is the human readable name of the algorithm as given in 122[the HTTP2 spec](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) 123for `Message-Encoding` (e.g. gzip, identity, etc.). See 124[`grpc_compression_algorithm_name`](https://github.com/grpc/grpc/blob/master/src/core/lib/compression/compression.c) 125for the mapping between the `grpc_compression_algorithm` enum values and their 126textual representation. 127 128## Per Message Settings 129 130To disable compression for a specific message, the `flags` field of `grpc_op` 131instances of type `GRPC_OP_SEND_MESSAGE` must have its `GRPC_WRITE_NO_COMPRESS` 132bit set. Refer to 133[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 134