Static vs dynamic compression in IIS
IIS ships two separate compression features, each backed by its own native module:
- Static Content Compression (
StaticCompressionModule) compresses files served by the static file handler — CSS, JavaScript, HTML files, SVG — and caches the compressed copy on disk so the work is done once. - Dynamic Content Compression (
DynamicCompressionModule) compresses responses generated per request — ASP.NET, PHP via FastCGI, proxied responses — on every request, without a disk cache.
Both can be active at the same time; each applies to its own type of content. Static compression is part of a default Web Server (IIS) installation on Windows Server. Dynamic compression is not, which is why the "Enable dynamic content compression" checkbox in IIS Manager is often greyed out with a message that the dynamic content compression module is not installed.
Feature names at a glance
| Feature | Server Manager / PowerShell (Windows Server) | DISM / optional feature (Windows 10/11) |
|---|---|---|
| Static Content Compression | Web-Stat-Compression | IIS-HttpCompressionStatic |
| Dynamic Content Compression | Web-Dyn-Compression | IIS-HttpCompressionDynamic |
Install on Windows Server (2016, 2019, 2022, 2025)
PowerShell
# Run in an elevated PowerShell session
Install-WindowsFeature -Name Web-Dyn-Compression
# Static as well, if it is missing
Install-WindowsFeature -Name Web-Stat-Compression
# Check what is installed
Get-WindowsFeature -Name Web-*Compression*
Server Manager
- Open Server Manager and choose Manage → Add Roles and Features.
- Go to Server Roles → Web Server (IIS) → Web Server → Performance.
- Tick Dynamic Content Compression (and Static Content Compression if unticked), then finish the wizard.
Install on Windows 10 and Windows 11
Client editions use optional features instead of server roles. Either use Turn Windows features on or off → Internet Information Services → World Wide Web Services → Performance Features → Dynamic Content Compression, or the command line:
# PowerShell (elevated)
Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompressionDynamic
Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompressionStatic
# or DISM from an elevated command prompt
dism /online /enable-feature /featurename:IIS-HttpCompressionDynamic
# Check
Get-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompression*
Verify the modules are registered
Installing the feature registers the native module with IIS. If DynamicCompressionModule is not listed, the feature did not install correctly:
%windir%\system32\inetsrv\appcmd.exe list modules | findstr /i compression
# Expected:
# MODULE "StaticCompressionModule" ( native, preCondition: )
# MODULE "DynamicCompressionModule" ( native, preCondition: )
If the feature refuses to install, the usual suspects are a pending reboot from earlier updates, a missing feature source on servers built from a trimmed image (point Install-WindowsFeature at installation media with -Source), or component-store corruption, which DISM /Online /Cleanup-Image /RestoreHealth addresses.
Turn compression on
Installing the module does not by itself compress anything. Enable it at server or site level — in IIS Manager open Compression and tick both boxes — or from the command line:
# appcmd: server-wide
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/urlCompression /doDynamicCompression:true /doStaticCompression:true /commit:apphost
# PowerShell (WebAdministration module)
Import-Module WebAdministration
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
-Filter 'system.webServer/urlCompression' -Name doDynamicCompression -Value $true
# Read the current settings for one site
Get-WebConfigurationProperty -PSPath 'IIS:\Sites\Default Web Site' `
-Filter 'system.webServer/urlCompression' -Name doDynamicCompression
The equivalent per-site setting in web.config is <urlCompression doStaticCompression="true" doDynamicCompression="true" /> inside <system.webServer>.
Add JSON and other MIME types
Dynamic compression only applies to MIME types listed under dynamicTypes in applicationHost.config. Depending on the Windows version, application/json may be missing, which is the classic reason Web API responses are not compressed. The httpCompression section is locked at server level by default, so add types there rather than in a site's web.config:
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost
The full list of settings (levels, static types, Brotli) is in the main IIS compression guide.
Check compression from outside IIS
You do not need access to the server to see whether compression is active. Request a page with an Accept-Encoding header and look for Content-Encoding in the response:
curl -s -o /dev/null -D - -H "Accept-Encoding: gzip" https://example.com/api/items | findstr /i "content-encoding vary"
# Linux/macOS: replace findstr with grep -iE '^(content-encoding|vary):'
Two IIS-specific behaviours confuse this test:
- Static files are not compressed on the first request. By default IIS compresses a static file only once it is requested frequently — two requests within ten seconds (the
frequentHitThresholdandfrequentHitTimePeriodsettings ofsystem.webServer/serverRuntime). Repeat the request, or lower the threshold to1if you want every static file compressed. - CPU throttling. IIS stops dynamic compression when CPU usage exceeds
dynamicCompressionDisableCpuUsage(90% by default) and resumes when it drops belowdynamicCompressionEnableCpuUsage(50% by default). A busy server can therefore serve some responses uncompressed.
The "IIS Temporary Compressed Files" error
Static compression stores compressed copies under %SystemDrive%\inetpub\temp\IIS Temporary Compressed Files, in a subfolder per application pool. When IIS cannot use that folder it logs a warning such as:
The directory specified for caching compressed content
C:\inetpub\temp\IIS Temporary Compressed Files\DefaultAppPool is invalid.
Static compression is being disabled.
The effect is exactly what it says: static files are served uncompressed for that application pool. That is not an outage, but it means larger downloads and slower page loads for CSS and JavaScript. Typical causes and fixes:
- The folder does not exist — for example after cleanup scripts, or when
inetpubwas moved. Recreate it, or pointhttpCompression'sdirectoryattribute at a valid path. - Permissions — the application pool identity needs modify rights. Granting
IIS_IUSRSmodify access on the parent folder covers the defaultApplicationPoolIdentityaccounts. - The directory points at a drive or share that is unavailable — use a local, always-present path.
icacls "C:\inetpub\temp\IIS Temporary Compressed Files" /grant "IIS_IUSRS:(OI)(CI)M"
iisreset
Is it safe to delete the temporary compressed files? Yes. They are a cache; IIS recreates them on demand. Delete them while the site is quiet (or after stopping the application pool) so files in use are not locked, and expect slightly higher CPU while the cache refills. The cache size per application pool is capped by maxDiskSpaceUsage on the httpCompression element.
Frequently asked questions
How do I install dynamic compression in IIS with PowerShell?
On Windows Server run Install-WindowsFeature -Name Web-Dyn-Compression in an elevated PowerShell. On Windows 10 or 11 run Enable-WindowsOptionalFeature -Online -FeatureName IIS-HttpCompressionDynamic.
Why is "Enable dynamic content compression" greyed out in IIS Manager?
The Dynamic Content Compression feature is not installed. Install Web-Dyn-Compression (Windows Server) or IIS-HttpCompressionDynamic (Windows 10/11), then reopen IIS Manager.
Can static and dynamic compression be enabled at the same time?
Yes. They are independent modules: static compression handles files served from disk and caches the result, dynamic compression handles generated responses on every request.
How do I check if dynamic compression is enabled without access to IIS?
Send a request with Accept-Encoding: gzip to a dynamic URL and look for Content-Encoding: gzip in the response headers, for example with curl -s -o /dev/null -D - -H "Accept-Encoding: gzip" URL.
Is it safe to delete the IIS Temporary Compressed Files folder contents?
Yes. The files are a cache of statically compressed content and IIS regenerates them. Keep the folder itself and its permissions, otherwise IIS disables static compression for the application pool.
Why does IIS not compress a static file on the first request?
IIS only compresses static files that are requested frequently: by default twice within ten seconds, controlled by frequentHitThreshold and frequentHitTimePeriod in system.webServer/serverRuntime.