Response Compression in ASP.NET

Feb 19 2024

Many thanks to the sponsors who make it possible for this newsletter to be free for readers.

 

• Streamline your API development with Postman's REST Client a powerful tool for sending requests, inspecting responses, and debugging REST APIs with ease. Discover a more efficient way to build and test APIs at link.

 
 

The Background

 
 

Since there's a limited amount of network bandwidth available, enhancing its efficiency can significantly boost the performance of your application.

 

A key method to achieve this is through response compression.

 

This technique focuses on minimizing the data size sent from the server to the client, which can substantially enhance the application's responsiveness.

 

Today, you will learn:

 

- How to configure response compression
- Compression Providers
- Custom Compression Providers
- Compression Levels
- Results?
- Why to use it and why not to use it.

 

Let's start...

 
 

Configuring Response Compression

 
 

The configuration of Response Compression is quite simple, it boils down to registering the middleware in DI:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression();

var app = builder.Build();

app.UseResponseCompression();

 

By default, this only works with the HTTP protocol.

 

If you want to enable HTTPS, it is necessary to add a setting:

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

 

Note:

 

Setting EnableForHttps to true is a security risk. See Compression with HTTPS in this article for more information.

 
 

Compression Providers

 
 

Compression providers compress or decompress data by applying a specific compression algorithm.

 

By using the AddResponseCompression method, you automatically get two compression providers:

 

1. BrotliCompressionProvider, which utilizes the Brotli algorithm. It is a more recent compression algorithm, and typically provides superior compression ratios compared to Gzip or Deflate. The BrotliCompressionProvider allows the server to use the Brotli algorithm for compressing data, which can then be decompressed by browsers that are equipped to handle Brotli compression.

 

2. GzipCompressionProvider, which employs the Gzip algorithm. Gzip is widely used in web applications for data compression. The GzipCompressionProvider enables the server to compress data using the Gzip algorithm and supports decompression in browsers that are compatible with Gzip compression.

 

The system defaults to Brotli for compression if the client can handle this format. In cases where the client doesn't support Brotli but does support Gzip, then Gzip is used as the default method.

 

It's crucial to remember that adding a specific compression provider means other providers are not included by default.

 

For example, if you specifically add only the Gzip compression provider, the system won't automatically include any other providers.

 

Here's a scenario demonstrating the activation of response compression for HTTPS requests with both Brotli and Gzip compression providers:

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

 
 

Custom Providers

 
 

You can develop tailored compression solutions using ICompressionProvider. This interface's EncodingName signifies the content encoding output produced by the ICompressionProvider.

 

The response compression middleware leverages this detail to select the appropriate provider, matching the encodings listed in the request's Accept-Encoding header.

 

In the example application, requests featuring the Accept-Encoding: mycustomcompression header receive responses labeled with a Content-Encoding: mycustomcompression header.

 

For such custom compression implementations to function effectively, the client should be capable of decompressing this unique encoding.

builder.Services.AddResponseCompression(options =>
{
    options.Providers.Add<MyCompressionProvider>();
});

 

MyCompressionProvider implementation:

public class MyCompressionProvider : ICompressionProvider
{
    public string EncodingName => "mufljuzcompression";
    public bool SupportsFlush => true;

    public Stream CreateStream(Stream outputStream)
    {
        // Replace with a custom compression stream wrapper.
        return outputStream;
    }
}

 
 

Compression Levels

 
 

Compression levels refer to the settings that determine the balance between the amount of compression applied to data and the computational resources (like time and processing power) required to perform the compression.

 

These levels are particularly relevant in data storage and transmission, where they influence file size and transfer speed.

 

You can setup a 4 possible values:

 

Optimal - balance response size and compression speed
Fastest - sacrifices optimal compression for improved speed (Default value)
NoCompression - there is no compression at all
SmallestSize - sacrifices compression speed to improve compression - to create a smaller response.

 

Example of setting the compression level:

builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
})

 
 

What we got?

 
 

I tested on the default API project in .NET with the WeatherForecast minimal API on .NET 8.

 

Without compression, on 10,000 records the response size is about ~700kB.

 

With BrotliCompressinProvider and CompressionLevel.SmallestSize setting response size is ~45kB.

 

Test the rest yourself :)

 
 

Why should you consider using it? And why not?

 
 

Response compression is a valuable technique in web development, offering significant benefits such as improved performance and efficient bandwidth usage.

 

By reducing the size of data transmitted between the server and the client, it enables faster loading times for web pages and applications, enhancing the overall user experience.

 

This efficiency in data transfer is particularly advantageous in environments with limited or costly network resources.

 

Additionally, faster loading times can lead to better search engine rankings, potentially increasing visibility and traffic.
Furthermore, response compression can result in cost savings, especially where bandwidth usage is a critical factor.

 

Why not?

 

However, there are considerations that might deter its use.

 

Compression processes consume CPU resources, which could increase server load, particularly on high-traffic sites.

 

This might introduce latency issues, especially in real-time applications where every millisecond counts.

 

It’s also important to note that response compression is not universally effective for all content types; already compressed files like JPEG images and video files see little benefit and may even slightly increase in size.

 

Implementing and maintaining response compression can add complexity to application development, and there could be compatibility issues with older browsers or specific client configurations, making it less ideal in certain scenarios.

 
 

What next?

 
 

Response compression is a cool trick for boosting your API's speed and cutting down on network expenses.

 

You should totally go for server-based compression if your server can handle it. If not, don't sweat it – .NET's got your back with its response compression middleware for application-based compression.

 

But what's the price tag on this?

 

Well, it's gonna make your CPU work harder and could open up some security gaps when using HTTPS.

 

However, you can totally find ways to work around these issues.

 

From what I've seen, sticking to the default settings for the compression provider and level usually works out pretty great.

 

That's all from me today.

Join 10,950+ subscribers to improve your .NET Knowledge.

There are 3 ways I can help you:

Design Patterns Simplified ebook

Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.


Sponsorship

Promote yourself to 10,950+ subscribers by sponsoring this newsletter.


Join .NET Pro Weekly Newsletter

Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.


Subscribe to
.NET Pro Weekly

Subscribe to the .NET Pro Weekly and be among the 10,950+ subscribers gaining practical tips and resources to enhance your .NET expertise.