IIS Compression Configuration Guide

Enable static and dynamic compression on Microsoft IIS for optimal performance

Quick Start: Enable IIS Compression

IIS supports both static and dynamic compression out of the box. Here's how to enable it:

1. Install Compression Features

# PowerShell (Run as Administrator)
# Windows Server 2019/2022
Install-WindowsFeature -Name Web-Dyn-Compression, Web-Stat-Compression

# Windows 10/11
Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompressionStatic
Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompressionDynamic

# Verify installation
Get-WindowsFeature | Where-Object {$_.Name -like "*Compression*"}

2. Enable via IIS Manager

  1. Open IIS Manager (inetmgr.exe)
  2. Select your server or site
  3. Double-click "Compression" in the IIS section
  4. Check "Enable dynamic content compression"
  5. Check "Enable static content compression"
  6. Click Apply

3. Basic web.config Configuration

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <urlCompression doStaticCompression="true" doDynamicCompression="true" />
        <staticContent>
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
        </staticContent>
    </system.webServer>
</configuration>

Advanced Compression Configuration

Fine-tune compression settings for optimal performance:

ApplicationHost.config Settings

<system.webServer>
    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files"
                     minFileSizeForComp="2700"
                     noCompressionForHttp10="false"
                     noCompressionForProxies="false">
        
        <!-- Static compression settings -->
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" 
                staticCompressionLevel="9" 
                dynamicCompressionLevel="4" />
        
        <!-- Dynamic content types -->
        <dynamicTypes>
            <add mimeType="text/*" enabled="true" />
            <add mimeType="message/*" enabled="true" />
            <add mimeType="application/javascript" enabled="true" />
            <add mimeType="application/json" enabled="true" />
            <add mimeType="application/xml" enabled="true" />
            <add mimeType="application/xhtml+xml" enabled="true" />
            <add mimeType="*/*" enabled="false" />
        </dynamicTypes>
        
        <!-- Static content types -->
        <staticTypes>
            <add mimeType="text/*" enabled="true" />
            <add mimeType="message/*" enabled="true" />
            <add mimeType="application/javascript" enabled="true" />
            <add mimeType="application/json" enabled="true" />
            <add mimeType="application/xml" enabled="true" />
            <add mimeType="application/xhtml+xml" enabled="true" />
            <add mimeType="application/atom+xml" enabled="true" />
            <add mimeType="application/rss+xml" enabled="true" />
            <add mimeType="font/otf" enabled="true" />
            <add mimeType="font/ttf" enabled="true" />
            <add mimeType="image/svg+xml" enabled="true" />
            <add mimeType="*/*" enabled="false" />
        </staticTypes>
    </httpCompression>
    
    <urlCompression doStaticCompression="true" 
                    doDynamicCompression="true" 
                    dynamicCompressionBeforeCache="true" />
</system.webServer>

PowerShell Configuration

# Import IIS module
Import-Module IISAdministration

# Set compression levels
Set-WebConfigurationProperty -Filter "system.webServer/httpCompression/scheme[@name='gzip']" `
    -Name "staticCompressionLevel" -Value 9
Set-WebConfigurationProperty -Filter "system.webServer/httpCompression/scheme[@name='gzip']" `
    -Name "dynamicCompressionLevel" -Value 4

# Enable compression for specific MIME types
Add-WebConfigurationProperty -Filter "system.webServer/httpCompression/dynamicTypes" `
    -Name "." -Value @{mimeType='application/json'; enabled='True'}

# Set minimum file size for compression (bytes)
Set-WebConfigurationProperty -Filter "system.webServer/httpCompression" `
    -Name "minFileSizeForComp" -Value 1024

# Apply changes
Restart-WebAppPool -Name "DefaultAppPool"

Enable Brotli Compression on IIS

Add Brotli support using the IIS Compression module:

1. Install IIS Compression Module

# Download from Microsoft
# https://www.iis.net/downloads/community/2020/03/iis-compression

# Or use PowerShell
Invoke-WebRequest -Uri "https://download.microsoft.com/download/6/1/C/61CC0718-ED0E-4351-BC54-46495EBF5CC3/iiscompression_amd64.msi" `
    -OutFile "iiscompression.msi"

# Install silently
msiexec /i iiscompression.msi /quiet /norestart

# Restart IIS
iisreset

2. Configure Brotli in ApplicationHost.config

<system.webServer>
    <httpCompression>
        <!-- Add Brotli scheme -->
        <scheme name="br" dll="%ProgramFiles%\IIS\IIS Compression\iisbrotli.dll" 
                staticCompressionLevel="11" 
                dynamicCompressionLevel="5" />
        
        <!-- Keep existing gzip -->
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" 
                staticCompressionLevel="9" 
                dynamicCompressionLevel="4" />
    </httpCompression>
</system.webServer>

3. Configure Response Headers

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Vary" value="Accept-Encoding" />
        </customHeaders>
    </httpProtocol>
    
    <rewrite>
        <outboundRules>
            <rule name="Add Encoding for Brotli">
                <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
                <conditions>
                    <add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
                </conditions>
                <action type="Rewrite" value="br" />
            </rule>
        </outboundRules>
    </rewrite>
</system.webServer>

Per-Site Compression Configuration

Configure compression for specific sites or applications:

Site-Specific web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <!-- Enable compression for this site -->
        <urlCompression doStaticCompression="true" doDynamicCompression="true" />
        
        <!-- Custom compression rules -->
        <httpCompression>
            <dynamicTypes>
                <clear />
                <add mimeType="text/*" enabled="true" />
                <add mimeType="application/javascript" enabled="true" />
                <add mimeType="application/json" enabled="true" />
                <add mimeType="application/xml" enabled="true" />
            </dynamicTypes>
        </httpCompression>
        
        <!-- Static file handling -->
        <staticContent>
            <!-- Enable compression for custom file types -->
            <mimeMap fileExtension=".json" mimeType="application/json" />
            <mimeMap fileExtension=".woff2" mimeType="font/woff2" />
            
            <!-- Client caching -->
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
        </staticContent>
        
        <!-- Disable compression for specific paths -->
        <location path="api/stream">
            <system.webServer>
                <urlCompression doStaticCompression="false" doDynamicCompression="false" />
            </system.webServer>
        </location>
    </system.webServer>
</configuration>

ASP.NET Core Compression

// Program.cs or Startup.cs
using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

// Add response compression services
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add();
    options.Providers.Add();
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "application/json", "image/svg+xml" });
});

// Configure compression levels
builder.Services.Configure(options =>
{
    options.Level = CompressionLevel.Optimal;
});

builder.Services.Configure(options =>
{
    options.Level = CompressionLevel.Optimal;
});

var app = builder.Build();

// Use compression middleware
app.UseResponseCompression();

Performance Optimization

CPU Threshold

Disable compression when CPU is high:

<httpCompression 
    staticCompressionDisableCpuUsage="90"
    dynamicCompressionDisableCpuUsage="80">

Compression Levels

Recommended settings by content type:

  • Static HTML/CSS/JS: Level 9
  • Dynamic content: Level 4-6
  • API responses: Level 1-4

Cache Integration

Compress before caching:

<urlCompression 
    dynamicCompressionBeforeCache="true" />

Testing IIS Compression

PowerShell Testing

# Test compression with PowerShell
$response = Invoke-WebRequest -Uri "https://localhost/test.css" `
    -Headers @{"Accept-Encoding"="gzip, deflate, br"}

# Check encoding
$response.Headers["Content-Encoding"]

# Compare sizes
$uncompressed = Invoke-WebRequest -Uri "https://localhost/test.css" `
    -Headers @{"Accept-Encoding"="identity"}

Write-Host "Compressed: $($response.RawContent.Length) bytes"
Write-Host "Uncompressed: $($uncompressed.RawContent.Length) bytes"
Write-Host "Ratio: $(($response.RawContent.Length / $uncompressed.RawContent.Length * 100))%"

Failed Request Tracing

<system.webServer>
    <tracing>
        <traceFailedRequests>
            <add path="*">
                <traceAreas>
                    <add provider="WWW Server" areas="Compression" verbosity="Verbose" />
                </traceAreas>
                <failureDefinitions statusCodes="200-999" />
            </add>
        </traceFailedRequests>
    </tracing>
</system.webServer>

Common IIS Compression Issues

Compression Not Working

  • Verify features are installed: Get-WindowsFeature *compression*
  • Check applicationHost.config for correct MIME types
  • Ensure file size is above minFileSizeForComp threshold
  • Verify no conflicting modules or handlers

Performance Issues

  • Monitor CPU usage during compression
  • Adjust compression levels based on server capacity
  • Use static compression for frequently accessed files
  • Consider hardware compression accelerators

Debugging Commands

# Check IIS compression status
%windir%\system32\inetsrv\appcmd list config -section:httpCompression

# View compression statistics
Get-Counter "\Web Service(_Total)\Total Compressed Files"
Get-Counter "\Web Service(_Total)\Total Compression Attempts"

# Check Event Viewer for compression errors
Get-EventLog -LogName System -Source W3SVC | Where-Object {$_.Message -like "*compression*"}

IIS Compression Best Practices

<!-- Optimal production configuration -->
<system.webServer>
    <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files"
                     minFileSizeForComp="1024"
                     staticCompressionDisableCpuUsage="95"
                     dynamicCompressionDisableCpuUsage="85">
        <scheme name="br" dll="%ProgramFiles%\IIS\IIS Compression\iisbrotli.dll" 
                staticCompressionLevel="11" dynamicCompressionLevel="5" />
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" 
                staticCompressionLevel="9" dynamicCompressionLevel="4" />
    </httpCompression>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" 
                    dynamicCompressionBeforeCache="true" />
</system.webServer>