Indiko.Blocks.API.Compression 2.1.2

dotnet add package Indiko.Blocks.API.Compression --version 2.1.2
                    
NuGet\Install-Package Indiko.Blocks.API.Compression -Version 2.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Indiko.Blocks.API.Compression" Version="2.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Indiko.Blocks.API.Compression" Version="2.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Indiko.Blocks.API.Compression" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Indiko.Blocks.API.Compression --version 2.1.2
                    
#r "nuget: Indiko.Blocks.API.Compression, 2.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Indiko.Blocks.API.Compression@2.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Indiko.Blocks.API.Compression&version=2.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Indiko.Blocks.API.Compression&version=2.1.2
                    
Install as a Cake Tool

Indiko.Blocks.API.Compression

Response compression block for reducing API response sizes using Gzip and Brotli compression algorithms.

Overview

This package provides automatic HTTP response compression for ASP.NET Core APIs, supporting both Gzip and Brotli compression with configurable compression levels and MIME types.

Features

  • Gzip Compression: Standard compression with wide browser support
  • Brotli Compression: Modern compression with better ratios
  • HTTPS Support: Configurable compression over HTTPS
  • MIME Type Filtering: Specify which content types to compress
  • Compression Levels: Adjustable compression levels (Fastest, Optimal, SmallestSize)
  • Automatic Negotiation: Client-side compression format negotiation
  • Performance: Significant bandwidth reduction (60-80% typical)

Installation

dotnet add package Indiko.Blocks.API.Compression

Quick Start

Enable Compression

// Compression is automatically enabled via block system
// when configured in appsettings.json

Configuration (appsettings.json)

{
  "CompressionOptions": {
    "Enabled": true,
    "EnableGzip": true,
    "EnableBrotli": true,
    "EnableForHttps": true,
    "MimeTypes": [
      "application/json",
      "application/xml",
      "text/plain",
      "text/html",
      "text/css",
      "text/javascript",
      "application/javascript"
    ]
  }
}

Compression Algorithms

Gzip

  • Browser Support: Universal (all modern browsers)
  • Compression Ratio: Good (~60-70% reduction)
  • Speed: Fast
  • Use Case: Default choice for broad compatibility

Brotli

  • Browser Support: Modern browsers (Chrome 50+, Firefox 44+, Edge 15+)
  • Compression Ratio: Excellent (~70-80% reduction)
  • Speed: Slightly slower than Gzip
  • Use Case: Best compression for modern clients

Configuration Options

CompressionOptions

public class CompressionOptions
{
    // Enable/disable compression
    public bool Enabled { get; set; } = true;
    
    // Enable Gzip compression
    public bool EnableGzip { get; set; } = true;
    
    // Enable Brotli compression
    public bool EnableBrotli { get; set; } = true;
    
    // Enable compression over HTTPS
    public bool EnableForHttps { get; set; } = true;
    
    // MIME types to compress
    public string[] MimeTypes { get; set; }
}

Full Configuration Example

{
  "CompressionOptions": {
    "Enabled": true,
    "EnableGzip": true,
    "EnableBrotli": true,
    "EnableForHttps": true,
    "MimeTypes": [
      "text/plain",
      "text/html",
      "text/xml",
      "text/css",
      "text/javascript",
      "application/javascript",
      "application/json",
      "application/xml",
      "application/x-javascript",
      "image/svg+xml"
    ]
  }
}

Compression Levels

Gzip Configuration

services.Configure<GzipCompressionProviderOptions>(options =>
{
    // Fastest compression (less CPU, larger files)
    options.Level = CompressionLevel.Fastest;
    
    // Optimal balance (default)
    options.Level = CompressionLevel.Optimal;
    
    // Smallest size (more CPU, smaller files)
    options.Level = CompressionLevel.SmallestSize;
});

Brotli Configuration

services.Configure<BrotliCompressionProviderOptions>(options =>
{
    // Similar levels available
    options.Level = CompressionLevel.Fastest;
    options.Level = CompressionLevel.Optimal;
    options.Level = CompressionLevel.SmallestSize;
});

Default Behavior

By default, the block uses:

  • Gzip: CompressionLevel.SmallestSize (best compression)
  • Brotli: CompressionLevel.Fastest (fast with good compression)

This balances performance and bandwidth savings.

How It Works

Content Negotiation

  1. Client sends request with Accept-Encoding header
  2. Server checks if content type should be compressed
  3. Server selects best compression algorithm (Brotli > Gzip)
  4. Response is compressed and sent with Content-Encoding header

Example Request/Response

Request:

GET /api/users HTTP/1.1
Host: api.example.com
Accept-Encoding: gzip, deflate, br

Response:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: br
Content-Length: 234
Vary: Accept-Encoding

[compressed content]

MIME Types

Default MIME Types

The block automatically compresses these types:

  • text/plain
  • text/css
  • text/html
  • text/xml
  • text/javascript
  • application/json
  • application/xml
  • application/javascript
  • application/x-javascript

Custom MIME Types

Add additional types in configuration:

{
  "CompressionOptions": {
    "MimeTypes": [
      "application/json",
      "application/xml",
      "image/svg+xml",
      "application/vnd.api+json",
      "application/x-protobuf"
    ]
  }
}

Exclusions

Don't Compress

Compression is NOT applied to:

  • Already Compressed: Images (JPEG, PNG, GIF), Videos, Audio files
  • Small Responses: Responses under ~1KB (overhead not worth it)
  • Streaming: Chunked transfer encoding
  • No Accept-Encoding: Clients that don't support compression

Example: Exclude Specific Endpoint

[HttpGet("large-binary")]
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
public IActionResult GetLargeBinary()
{
    // This endpoint returns pre-compressed data
    Response.Headers.Add("Content-Encoding", "identity");
    return File(binaryData, "application/octet-stream");
}

Performance Impact

Bandwidth Savings

Content Type Uncompressed Gzip Brotli
JSON (API) 100 KB 30 KB 25 KB
HTML 50 KB 15 KB 12 KB
JavaScript 200 KB 60 KB 50 KB
CSS 100 KB 20 KB 15 KB

Average Savings: 60-80% bandwidth reduction

CPU Impact

  • Gzip: ~2-5ms additional server processing
  • Brotli: ~5-10ms additional server processing

For most APIs, this is negligible compared to network transfer time.

HTTPS Compression

Security Consideration

Compression over HTTPS can theoretically be vulnerable to attacks like BREACH. However, for APIs:

  1. APIs rarely reflect user input in responses
  2. BREACH requires specific attack conditions
  3. Benefits typically outweigh risks for APIs

Enable/Disable

{
  "CompressionOptions": {
    "EnableForHttps": true  // Set to false if concerned about BREACH
  }
}

Testing Compression

Using cURL

# Test Gzip
curl -H "Accept-Encoding: gzip" -I https://api.example.com/api/users

# Test Brotli
curl -H "Accept-Encoding: br" -I https://api.example.com/api/users

# Response should include:
# Content-Encoding: br (or gzip)

Using Browser DevTools

  1. Open Developer Tools (F12)
  2. Go to Network tab
  3. Make API request
  4. Check response headers for Content-Encoding
  5. Compare Size (compressed) vs Content (uncompressed)

Best Practices

  1. Enable Both: Support both Gzip and Brotli for broad compatibility
  2. Compress Text Only: Don't compress images, videos, or already-compressed files
  3. Monitor Performance: Track CPU usage and response times
  4. Adjust Levels: Use faster compression for high-traffic endpoints
  5. Cache Headers: Combine with response caching for better performance
  6. CDN: Use CDN compression if available

Advanced Configuration

Conditional Compression

public class ConditionalCompressionBlock : CompressionBlock
{
    public override void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression(options =>
        {
            options.EnableForHttps = true;
            
            // Custom condition
            options.Providers.Add<GzipCompressionProvider>();
            options.Providers.Add<BrotliCompressionProvider>();
            
            // Only compress responses > 4KB
            options.MimeTypes = ResponseCompressionDefaults.MimeTypes;
        });
    }
}

Per-Endpoint Control

[HttpGet]
[ResponseCache(VaryByHeader = "Accept-Encoding")]
public IActionResult GetData()
{
    // Compression applied automatically
    return Ok(data);
}

[HttpGet("no-compression")]
public IActionResult GetUncompressedData()
{
    // Disable compression for this endpoint
    Response.Headers.Add("Content-Encoding", "identity");
    return Ok(data);
}

Environment-Specific Configuration

Development (Faster)

{
  "CompressionOptions": {
    "Enabled": true,
    "EnableGzip": true,
    "EnableBrotli": false,  // Disable for faster dev server
    "EnableForHttps": true
  }
}

Production (Best Compression)

{
  "CompressionOptions": {
    "Enabled": true,
    "EnableGzip": true,
    "EnableBrotli": true,  // Enable for best compression
    "EnableForHttps": true
  }
}

Monitoring

Key Metrics

  • Compression Ratio: Uncompressed size / Compressed size
  • CPU Usage: Monitor server CPU during compression
  • Response Time: Total time including compression
  • Bandwidth Savings: Network bytes saved

Logging

public class CompressionLoggingMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var originalBodyStream = context.Response.Body;
        
        using var memoryStream = new MemoryStream();
        context.Response.Body = memoryStream;
        
        await next(context);
        
        var uncompressedSize = memoryStream.Length;
        memoryStream.Position = 0;
        
        await memoryStream.CopyToAsync(originalBodyStream);
        
        var encoding = context.Response.Headers["Content-Encoding"].ToString();
        var compressedSize = context.Response.ContentLength ?? uncompressedSize;
        
        _logger.LogInformation(
            "Compressed response: {UncompressedSize} ? {CompressedSize} bytes ({Encoding})",
            uncompressedSize, compressedSize, encoding);
    }
}

Troubleshooting

Compression Not Working

  1. Check Accept-Encoding header in request
  2. Verify MIME type is in configuration
  3. Ensure response is not already compressed
  4. Check if Enabled = true in configuration
  5. Verify middleware order (UseResponseCompression should be early)

Performance Issues

  1. Reduce compression level (use Fastest)
  2. Increase minimum response size threshold
  3. Disable Brotli, use only Gzip
  4. Consider CDN compression instead

Target Framework

  • .NET 10

Dependencies

  • Microsoft.AspNetCore.ResponseCompression
  • Indiko.Blocks.Common.Abstractions

License

See LICENSE file in the repository root.

  • Indiko.Blocks.API.Swagger - API documentation
  • Indiko.Blocks.API.FeatureManagement - Feature flags
  • Indiko.Blocks.API.Idempotency - Idempotent requests
  • Indiko.Hosting.Web - Web API hosting
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.2 124 12/18/2025
2.1.1 656 12/2/2025
2.1.0 655 12/2/2025
2.0.0 291 9/17/2025
1.7.23 180 9/8/2025
1.7.22 172 9/8/2025
1.7.21 168 8/14/2025
1.7.20 176 6/23/2025
1.7.19 167 6/3/2025
1.7.18 179 5/29/2025
1.7.17 168 5/26/2025
1.7.15 117 4/12/2025
1.7.14 156 4/11/2025
1.7.13 139 3/29/2025
1.7.12 141 3/28/2025
1.7.11 159 3/28/2025
1.7.10 156 3/28/2025
1.7.9 151 3/28/2025
1.7.8 144 3/28/2025
1.7.5 180 3/17/2025
1.7.4 164 3/16/2025
1.7.3 175 3/16/2025
1.7.2 178 3/16/2025
1.7.1 207 3/11/2025
1.6.8 204 3/11/2025
1.6.7 256 3/4/2025
1.6.6 138 2/26/2025
1.6.5 136 2/20/2025
1.6.4 116 2/20/2025
1.6.3 135 2/5/2025
1.6.2 115 1/24/2025
1.6.1 128 1/24/2025
1.6.0 121 1/16/2025
1.5.2 112 1/16/2025
1.5.1 155 11/3/2024
1.5.0 141 10/26/2024
1.3.2 141 10/24/2024
1.3.0 145 10/10/2024
1.2.5 148 10/9/2024
1.2.4 152 10/8/2024
1.2.1 128 10/3/2024
1.2.0 153 9/29/2024
1.1.1 137 9/23/2024
1.1.0 142 9/18/2024
1.0.33 161 9/15/2024
1.0.28 149 8/28/2024
1.0.27 166 8/24/2024
1.0.26 174 7/7/2024
1.0.25 169 7/6/2024
1.0.24 144 6/25/2024
1.0.23 149 6/1/2024
1.0.22 168 5/14/2024
1.0.21 140 5/14/2024
1.0.20 157 4/8/2024
1.0.19 162 4/3/2024
1.0.18 163 3/23/2024
1.0.17 180 3/19/2024
1.0.16 156 3/19/2024
1.0.15 170 3/11/2024
1.0.14 188 3/10/2024
1.0.13 137 3/6/2024
1.0.12 171 3/1/2024
1.0.11 160 3/1/2024
1.0.10 147 3/1/2024
1.0.9 160 3/1/2024
1.0.8 148 2/19/2024
1.0.7 164 2/17/2024
1.0.6 148 2/17/2024
1.0.5 166 2/17/2024
1.0.4 165 2/7/2024
1.0.3 136 2/6/2024
1.0.1 154 2/6/2024
1.0.0 187 1/9/2024
1.0.0-preview99 183 12/22/2023
1.0.0-preview98 143 12/21/2023
1.0.0-preview97 151 12/21/2023
1.0.0-preview96 149 12/20/2023
1.0.0-preview94 129 12/18/2023
1.0.0-preview93 176 12/13/2023
1.0.0-preview92 155 12/13/2023
1.0.0-preview91 151 12/12/2023
1.0.0-preview90 166 12/11/2023
1.0.0-preview89 145 12/11/2023
1.0.0-preview101 136 1/5/2024