gRPC Server Response Compression - C#, ASP.NET Core

26 views
Skip to first unread message

Ameen Sherif

unread,
Jul 3, 2025, 4:54:31 PM7/3/25
to grpc.io
Hi,
We have a gRPC client and server where the server is capable of sending binary data ranging from 100 MB to 5 gig based on the client request. Maximum chunk size is 512 MB, meaning data above 512 is chunked and streamed. For eg: if it is 1000 MB, it will be streamed as 512 MB and 488 MB.
We have decided to test the impact of introducing compression and facing some issues in getting it done. 
Application and hosting details
Hosting and dev Environment

  •   Framework: ASP.NET Core (C#)
  •  Server: Kestrel (built-in web server for ASP.NET Core)
  • Protocol: HTTP/2 (required for gRPC)
  • goog_1490578365Security: HTTPS with TLS (certificate-based encryption)
  • <TargetFramework>net8.0</TargetFramework>
  • <PackageReference Include="Grpc.AspNetCore" Version="2.54.0" />


Problem Statement:

The issue began when we observed that even though the gRPC client sends the grpc-accept-encoding: identity,gzip header (confirmed via logs), the server logs still reported:
Client supports response compression: none

Current Implementation:
Server side:

builder.Services.AddGrpc(options =>
{
    options.MaxReceiveMessageSize = int.MaxValue;
    options.MaxSendMessageSize = int.MaxValue;

    if (useCompression)
    {
        options.ResponseCompressionAlgorithm = "gzip";
        options.ResponseCompressionLevel = CompressionLevel.Fastest;

        //Register compression provider
        options.CompressionProviders = new List<Grpc.Net.Compression.ICompressionProvider>
        {
            new Grpc.Net.Compression.GzipCompressionProvider(System.IO.Compression.CompressionLevel.Fastest)
        };

        options.Interceptors.Add<CompressionLoggingInterceptor>();
    }
});

Client Side:

var compressionProviders = new List<ICompressionProvider>
{
    new GzipCompressionProvider(CompressionLevel.Fastest)
};

if (!useTls)
{
    var handler = new SocketsHttpHandler();
    handler.EnableMultipleHttp2Connections = true;
    var loggingHandler = new LoggingHandler(handler);
    var channelOptions = new GrpcChannelOptions
    {
        HttpHandler = loggingHandler,
        MaxReceiveMessageSize = int.MaxValue,
        CompressionProviders = compressionProviders

    };
    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
    //channelOptions.HttpHandler = new HttpClientHandler();
    return GrpcChannel.ForAddress(address, channelOptions);
}

What Theory Says – If compression is enabled during channel creation, the client will send header compression header (grpc-accept-encoding: identity,gzip) and server can will decide on this. Here only the server response will be compressed, not the client and that is we are trying to attain.  

But the server log says "Client supports response compression: none"

A detailed search on it suggested explicitly requesting compression per message, but both of the below options were not usable with the project setup.  

var callOptions = new CallOptions()

    .WithWriteOptions(new WriteOptions(WriteFlags.UseCompression)); Note: this is to explicitly set compression request per message.

var response = await client.MyRpcMethodAsync(new MyRequest(), callOptions);

But we cannot use WriteFlags.UseCompression in ASP.NET core and Grpc.Net.Client

OR

var callOptions = Grpc.Net.Client.GrpcCallOptionsExtensions.WithCompression(new CallOptions(), "gzip");

using var call = client.RequestData(request, callOptions);

 Both of them were not available. 


What we are looking for. 

A solution to tackle the issue or sample compression implementation using gRPC and ASP.NET core



Reply all
Reply to author
Forward
0 new messages