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
<PackageReference Include="Indiko.Blocks.API.Compression" Version="2.1.2" />
<PackageVersion Include="Indiko.Blocks.API.Compression" Version="2.1.2" />
<PackageReference Include="Indiko.Blocks.API.Compression" />
paket add Indiko.Blocks.API.Compression --version 2.1.2
#r "nuget: Indiko.Blocks.API.Compression, 2.1.2"
#:package Indiko.Blocks.API.Compression@2.1.2
#addin nuget:?package=Indiko.Blocks.API.Compression&version=2.1.2
#tool nuget:?package=Indiko.Blocks.API.Compression&version=2.1.2
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
- Client sends request with
Accept-Encodingheader - Server checks if content type should be compressed
- Server selects best compression algorithm (Brotli > Gzip)
- Response is compressed and sent with
Content-Encodingheader
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/plaintext/csstext/htmltext/xmltext/javascriptapplication/jsonapplication/xmlapplication/javascriptapplication/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:
- APIs rarely reflect user input in responses
- BREACH requires specific attack conditions
- 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
- Open Developer Tools (F12)
- Go to Network tab
- Make API request
- Check response headers for
Content-Encoding - Compare
Size(compressed) vsContent(uncompressed)
Best Practices
- Enable Both: Support both Gzip and Brotli for broad compatibility
- Compress Text Only: Don't compress images, videos, or already-compressed files
- Monitor Performance: Track CPU usage and response times
- Adjust Levels: Use faster compression for high-traffic endpoints
- Cache Headers: Combine with response caching for better performance
- 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
- Check
Accept-Encodingheader in request - Verify MIME type is in configuration
- Ensure response is not already compressed
- Check if Enabled = true in configuration
- Verify middleware order (UseResponseCompression should be early)
Performance Issues
- Reduce compression level (use Fastest)
- Increase minimum response size threshold
- Disable Brotli, use only Gzip
- Consider CDN compression instead
Target Framework
- .NET 10
Dependencies
Microsoft.AspNetCore.ResponseCompressionIndiko.Blocks.Common.Abstractions
License
See LICENSE file in the repository root.
Related Packages
Indiko.Blocks.API.Swagger- API documentationIndiko.Blocks.API.FeatureManagement- Feature flagsIndiko.Blocks.API.Idempotency- Idempotent requestsIndiko.Hosting.Web- Web API hosting
| Product | Versions 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. |
-
net10.0
- Indiko.Blocks.Common.Abstractions (>= 2.1.2)
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 |