Skip to content

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:

// MicroserviceRegistrationExtensions.cs
application.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:

{
  "Compression": {
    "Providers": {
      "Brotli": {
        "Level": "Optimal"
      }
    }
  }
}

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:

{
  "Compression": {
    "Providers": {
      "Gzip": {
        "Level": "Optimal"
      }
    }
  }
}

Default MIME Types

The middleware compresses the following MIME types by default:

  • application/json
  • application/xml
  • text/plain
  • text/css
  • text/html
  • text/xml
  • application/javascript
  • application/atom+xml
  • application/rss+xml
  • text/javascript
  • application/json; charset=utf-8
  • text/html; charset=utf-8
  • text/xml; charset=utf-8
  • application/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:

  1. Default to Disabled for HTTPS (recommended):

    {
      "Compression": {
        "EnableForHttps": false
      }
    }
    

  2. Enable Only When Necessary:

  3. Only enable HTTPS compression if you understand the security implications
  4. Ensure you have appropriate mitigations in place
  5. Consider using HTTPS compression only for non-sensitive content

  6. Mitigation Strategies:

  7. Use Content Security Policy (CSP) headers
  8. Implement CSRF protection
  9. Avoid including sensitive data in compressed responses
  10. Use separate endpoints for sensitive vs. non-sensitive content

Best Practices

Do's

  1. Enable Compression in Production

    {
      "Compression": {
        "Enabled": true
      }
    }
    

  2. Use Optimal Compression Level

    {
      "Compression": {
        "Providers": {
          "Brotli": { "Level": "Optimal" },
          "Gzip": { "Level": "Optimal" }
        }
      }
    }
    

  3. Keep HTTPS Compression Disabled by Default

    {
      "Compression": {
        "EnableForHttps": false
      }
    }
    

  4. Compress Text-Based Content

    {
      "Compression": {
        "MimeTypes": [
          "application/json",
          "application/xml",
          "text/plain",
          "text/css",
          "application/javascript"
        ]
      }
    }
    

  5. Monitor Compression Metrics

  6. Track compression ratios
  7. Monitor CPU usage
  8. Measure response size reduction
  9. Monitor bandwidth savings

Don'ts

  1. Don't Compress Already-Compressed Content

    // ❌ BAD - Images, videos, PDFs are already compressed
    {
      "Compression": {
        "MimeTypes": [
          "image/jpeg",
          "image/png",
          "video/mp4",
          "application/pdf"
        ]
      }
    }
    

  2. Don't Enable HTTPS Compression Without Understanding Risks

    // ❌ BAD - Security risk without proper mitigations
    {
      "Compression": {
        "EnableForHttps": true
      }
    }
    

  3. Don't Use SmallestSize for High-Traffic Scenarios

    // ❌ BAD - High CPU usage may impact performance
    {
      "Compression": {
        "Providers": {
          "Brotli": { "Level": "SmallestSize" }
        }
      }
    }
    

  4. Don't Disable Compression Without Good Reason

    // ❌ BAD - Missing performance optimization
    {
      "Compression": {
        "Enabled": false
      }
    }
    

Troubleshooting

Issue: Responses Not Being Compressed

Symptoms: Responses are not compressed even though compression is enabled.

Solutions:

  1. Verify Compression is Enabled

    {
      "Compression": {
        "Enabled": true
      }
    }
    

  2. Check Middleware Order

    // ✅ GOOD - Correct order
    application.UseRouting();
    application.UseMicroserviceCompression();
    application.UseStaticFiles();
    

  3. Verify Accept-Encoding Header

  4. Client must send Accept-Encoding: br, gzip header
  5. Check browser developer tools Network tab
  6. Verify client supports compression

  7. Check MIME Type

  8. Verify response Content-Type is in the compressed MIME types list
  9. Check default MIME types or add custom MIME types

  10. Check Response Size

  11. Compression may not be applied to very small responses
  12. Minimum size threshold may prevent compression

Issue: High CPU Usage

Symptoms: High CPU usage after enabling compression.

Solutions:

  1. Use Fastest Compression Level

    {
      "Compression": {
        "Providers": {
          "Brotli": { "Level": "Fastest" },
          "Gzip": { "Level": "Fastest" }
        }
      }
    }
    

  2. Limit Compressed MIME Types

    {
      "Compression": {
        "MimeTypes": [
          "application/json",
          "text/plain"
        ]
      }
    }
    

  3. Monitor Compression Ratios

  4. Disable compression for content that doesn't compress well
  5. Focus compression on text-based content

Issue: Compression Not Working for HTTPS

Symptoms: HTTPS responses are not compressed.

Solutions:

  1. Enable HTTPS Compression (with security considerations)

    {
      "Compression": {
        "EnableForHttps": true
      }
    }
    

  2. Verify Security Implications

  3. Understand CRIME/BREACH attack vectors
  4. Implement appropriate mitigations
  5. 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 Compression and UseGrpc feature 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.

References