Response Compression Middleware in ConnectSoft Microservice Template¶
Purpose & Overview¶
Response Compression Middleware compresses HTTP responses to reduce bandwidth usage and improve performance. In the ConnectSoft Microservice Template, response compression is implemented using ASP.NET Core's built-in response compression middleware, providing configurable compression with Brotli and Gzip providers.
Response compression provides:
- Bandwidth Reduction: Significantly reduces the size of HTTP responses, especially for text-based content
- Performance Improvement: Faster response times, especially on slower network connections
- Cost Savings: Reduces bandwidth costs for cloud-hosted applications
- Better User Experience: Faster page loads and API responses
- SEO Benefits: Faster page loads improve search engine rankings
- Mobile Optimization: Particularly beneficial for mobile users on slower connections
Response Compression Philosophy
Response compression is a performance optimization that should be enabled for most production scenarios. The template provides configurable compression with Brotli and Gzip providers, allowing you to balance compression ratio with CPU usage. Compression is most effective for text-based content (JSON, XML, HTML, CSS, JavaScript) and less effective for already-compressed content (images, videos, PDFs).
Architecture Overview¶
Response Compression in the Request Pipeline¶
Incoming Request
↓
HTTPS Redirection (UseHttpsRedirection)
↓
Routing Middleware (UseRouting)
↓
Response Compression Middleware (UseResponseCompression)
├── Check if compression is enabled
├── Check Accept-Encoding header
├── Select compression provider (Brotli > Gzip)
├── Compress response body
│ ├── Brotli (preferred, better compression)
│ └── Gzip (fallback, wider compatibility)
↓
Controller/Endpoint
↓
Compressed Response
↓
Client (decompresses automatically)
Configuration¶
Service Registration¶
AddMicroserviceCompression:
// CompressionExtensions.cs
internal static IServiceCollection AddMicroserviceCompression(
this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
var options = OptionsExtensions.CompressionOptions;
if (options?.Enabled == true)
{
services.AddResponseCompression(compressionOptions =>
{
compressionOptions.EnableForHttps = options.EnableForHttps;
if (options.MimeTypes != null && options.MimeTypes.Count > 0)
{
compressionOptions.MimeTypes = ResponseCompressionDefaults.MimeTypes
.Concat(options.MimeTypes);
}
compressionOptions.Providers.Add<BrotliCompressionProvider>();
compressionOptions.Providers.Add<GzipCompressionProvider>();
});
services.Configure<BrotliCompressionProviderOptions>(providerOptions =>
{
providerOptions.Level = options.Providers?.Brotli?.Level
?? CompressionLevel.Optimal;
});
services.Configure<GzipCompressionProviderOptions>(providerOptions =>
{
providerOptions.Level = options.Providers?.Gzip?.Level
?? CompressionLevel.Optimal;
});
}
return services;
}
Middleware Registration¶
UseMicroserviceCompression:
Pipeline Position:
// Middleware order:
application.UseHttpsRedirection();
application.UseRouting(); // Before compression
application.UseMicroserviceCompression(); // After routing
application.UseStaticFiles(); // After compression
application.UseEndpoints(...); // After compression
Important: Response compression middleware must be placed:
- After UseRouting() (to access route information)
- Before UseStaticFiles() (to allow caching compressed static files)
- Before UseEndpoints() (to compress dynamic responses)
Configuration Options¶
CompressionOptions¶
Configuration Class:
// CompressionOptions.cs
public sealed class CompressionOptions
{
public const string CompressionOptionsSectionName = "Compression";
[Required]
required public bool Enabled { get; set; } = true;
public bool EnableForHttps { get; set; } = false;
public List<string>? MimeTypes { get; set; }
[ValidateObjectMembers]
public CompressionProviderOptions? Providers { get; set; }
}
CompressionProviderOptions¶
Configuration Class:
// CompressionOptions.cs
public sealed class CompressionProviderOptions
{
[ValidateObjectMembers]
public BrotliCompressionProviderOptions? Brotli { get; set; }
[ValidateObjectMembers]
public GzipCompressionProviderOptions? Gzip { get; set; }
}
public sealed class BrotliCompressionProviderOptions
{
public CompressionLevel Level { get; set; } = CompressionLevel.Optimal;
}
public sealed class GzipCompressionProviderOptions
{
public CompressionLevel Level { get; set; } = CompressionLevel.Optimal;
}
appsettings.json Configuration¶
Example Configuration:
{
"Compression": {
"Enabled": true,
"EnableForHttps": false,
"MimeTypes": [
"application/json",
"application/xml",
"text/plain",
"text/css",
"application/javascript"
],
"Providers": {
"Brotli": {
"Level": "Optimal"
},
"Gzip": {
"Level": "Optimal"
}
}
}
}
Configuration Parameters:
| Parameter | Type | Description | Default | Example |
|---|---|---|---|---|
Enabled |
bool |
Enable or disable response compression middleware | true |
true |
EnableForHttps |
bool |
Enable compression for HTTPS requests (security consideration) | false |
false |
MimeTypes |
List<string> |
Custom MIME types to compress (optional, defaults are used if not specified) | null |
["application/json", "text/plain"] |
Providers |
CompressionProviderOptions |
Compression provider configuration | null |
See below |
CompressionProviderOptions Parameters:
| Parameter | Type | Description | Default | Example |
|---|---|---|---|---|
Brotli |
BrotliCompressionProviderOptions |
Brotli compression provider options | null |
See below |
Gzip |
GzipCompressionProviderOptions |
Gzip compression provider options | null |
See below |
Compression Level Options:
| Level | Description | Compression Ratio | CPU Usage | Use Case |
|---|---|---|---|---|
Fastest |
Fastest compression | Lower | Lowest | High-traffic scenarios, real-time applications |
Optimal |
Balanced compression | Balanced | Balanced | Recommended default for most scenarios |
SmallestSize |
Maximum compression | Highest | Highest | Low-traffic scenarios, maximum bandwidth savings |
NoCompression |
No compression | N/A | N/A | Disable compression for specific provider |
Compression Providers¶
Brotli Compression¶
Brotli is a modern compression algorithm that provides better compression ratios than Gzip:
- Better Compression: Typically 15-20% better compression than Gzip
- Modern Browsers: Supported by all modern browsers
- Preferred Provider: Used when client supports it (via Accept-Encoding header)
Configuration:
Gzip Compression¶
Gzip is a widely supported compression algorithm:
- Universal Support: Supported by virtually all browsers and HTTP clients
- Fallback Provider: Used when Brotli is not supported
- Good Compression: Provides good compression ratios for text-based content
Configuration:
Default MIME Types¶
The middleware compresses the following MIME types by default:
application/jsonapplication/xmltext/plaintext/csstext/htmltext/xmlapplication/javascriptapplication/atom+xmlapplication/rss+xmltext/javascriptapplication/json; charset=utf-8text/html; charset=utf-8text/xml; charset=utf-8application/xml; charset=utf-8
Custom MIME Types¶
Add custom MIME types to compress additional content:
{
"Compression": {
"MimeTypes": [
"application/json",
"application/vnd.api+json",
"text/markdown"
]
}
}
Security Considerations¶
HTTPS Compression (CRIME/BREACH Attacks)¶
HTTPS Compression Security Risk
Enabling compression for HTTPS requests can expose your application to CRIME (Compression Ratio Info-leak Made Easy) and BREACH (Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext) attacks. These attacks exploit compression to extract sensitive information from encrypted responses.
Recommendations:
-
Default to Disabled for HTTPS (recommended):
-
Enable Only When Necessary:
- Only enable HTTPS compression if you understand the security implications
- Ensure you have appropriate mitigations in place
-
Consider using HTTPS compression only for non-sensitive content
-
Mitigation Strategies:
- Use Content Security Policy (CSP) headers
- Implement CSRF protection
- Avoid including sensitive data in compressed responses
- Use separate endpoints for sensitive vs. non-sensitive content
Best Practices¶
Do's¶
-
Enable Compression in Production
-
Use Optimal Compression Level
-
Keep HTTPS Compression Disabled by Default
-
Compress Text-Based Content
-
Monitor Compression Metrics
- Track compression ratios
- Monitor CPU usage
- Measure response size reduction
- Monitor bandwidth savings
Don'ts¶
-
Don't Compress Already-Compressed Content
-
Don't Enable HTTPS Compression Without Understanding Risks
-
Don't Use SmallestSize for High-Traffic Scenarios
-
Don't Disable Compression Without Good Reason
Troubleshooting¶
Issue: Responses Not Being Compressed¶
Symptoms: Responses are not compressed even though compression is enabled.
Solutions:
-
Verify Compression is Enabled
-
Check Middleware Order
-
Verify Accept-Encoding Header
- Client must send
Accept-Encoding: br, gzipheader - Check browser developer tools Network tab
-
Verify client supports compression
-
Check MIME Type
- Verify response Content-Type is in the compressed MIME types list
-
Check default MIME types or add custom MIME types
-
Check Response Size
- Compression may not be applied to very small responses
- Minimum size threshold may prevent compression
Issue: High CPU Usage¶
Symptoms: High CPU usage after enabling compression.
Solutions:
-
Use Fastest Compression Level
-
Limit Compressed MIME Types
-
Monitor Compression Ratios
- Disable compression for content that doesn't compress well
- Focus compression on text-based content
Issue: Compression Not Working for HTTPS¶
Symptoms: HTTPS responses are not compressed.
Solutions:
-
Enable HTTPS Compression (with security considerations)
-
Verify Security Implications
- Understand CRIME/BREACH attack vectors
- Implement appropriate mitigations
- Consider using HTTPS compression only for non-sensitive content
gRPC Compression¶
The template also supports compression for gRPC services, which is separate from HTTP response compression:
Differences Between HTTP and gRPC Compression¶
| Aspect | HTTP Response Compression | gRPC Compression |
|---|---|---|
| Headers | Content-Encoding, Accept-Encoding |
grpc-encoding, grpc-accept-encoding |
| Configuration | CompressionOptions section |
GrpcOptions section |
| Providers | Microsoft.AspNetCore.ResponseCompression |
Grpc.Net.Compression |
| Protocol | HTTP/1.1, HTTP/2 | gRPC (HTTP/2) |
| Feature Flag | Compression |
Compression + UseGrpc |
gRPC Compression Configuration¶
gRPC compression is configured in the Grpc section of appsettings.json:
{
"Grpc": {
"ResponseCompressionAlgorithm": "gzip", // "gzip", "br", "deflate", or null
"ResponseCompressionLevel": "Optimal" // Fastest, Optimal, SmallestSize
}
}
When to Use Each¶
- HTTP Response Compression: Use for REST APIs, web pages, static files, and HTTP/1.1 or HTTP/2 traffic
- gRPC Compression: Use for gRPC services when both
CompressionandUseGrpcfeature flags are enabled
Both can be enabled simultaneously - they operate independently and use different headers and mechanisms.
For more details, see the gRPC documentation in ConnectSoft.Documentation.
Summary¶
Response compression middleware in the ConnectSoft Microservice Template provides:
- ✅ Brotli and Gzip Support: Modern Brotli compression with Gzip fallback
- ✅ Configurable Compression Levels: Balance compression ratio with CPU usage
- ✅ Custom MIME Types: Configure which content types to compress
- ✅ HTTPS Security: Default disabled for HTTPS to prevent CRIME/BREACH attacks
- ✅ Production Ready: Configurable for different environments
- ✅ Performance Optimized: Reduces bandwidth usage and improves response times
By following these patterns, teams can:
- Reduce Bandwidth: Significantly reduce response sizes, especially for text-based content
- Improve Performance: Faster response times, especially on slower connections
- Save Costs: Reduce bandwidth costs for cloud-hosted applications
- Enhance User Experience: Faster page loads and API responses
- Optimize Mobile: Particularly beneficial for mobile users on slower connections
Response compression is an essential performance optimization that should be enabled for most production scenarios, with careful consideration of security implications for HTTPS traffic.