Script to Enable HTTP Compression (Gzip/Deflate) in IIS 6


One of the easiest ways to improve web site performance is to enable HTTP compression (often referred to as GZIP compression), which trades CPU time to compress content for a reduced payload delivered over the wire. In the vast majority of cases, the trade-off is a good one.

When implementing HTTP compression, your content will break down into three categories:

  1. Content that should not be compressed because it is already compressed: images, PDF files, audio, video, etc.
  2. Static content that can be compressed once and cached for later.
  3. Dynamic content that needs to be compressed for every request.

Excluding already-compressed content will need to be considered regardless of the techniques used to compress categories 2 and 3.

Since version 5, IIS has included support for both kinds of HTTP compression. This can be enabled through the management interface, but you will almost certainly want to tweak the default configuration in the metabase (see script below). While IIS works great for compressing static files, its extension-based configuration is rather limited when serving up dynamic content, especially if you don’t use extensions (as with most ASP.NET MVC routes) or you serve dynamic content that should not be compressed. A better solution is provided in HttpCompress by Ben Lowery, a configurable HttpModule that allows content to be excluded from compression by MIME type. A standard configuration might look something like this:

<configuration>
...
<blowery.web>
<httpCompress preferredAlgorithm="gzip" compressionLevel="normal">
<excludedMimeTypes>
<add type="image/jpeg" />
<add type="image/png" />
<add type="image/gif" />
<add type="application/pdf" />
</excludedMimeTypes>
<excludedPaths></excludedPaths>
</httpCompress>
</blowery.web>
...
</configuration>

To supplement the compressed dynamic content, you should also enable static compression for the rest of your not-already-compressed content. The script should be pretty self-explanatory, but I’ll draw attention to a few things:

  • The tcfpath variable at the top is currently set to IIS’s default location, which you are free to change.
  • The extlist variable accepts a space-delimited list of file extensions that should be compressed. Again, only include files types that are not already compressed, as recompressing a file wastes cycles and can actually make some files larger.
  • There are a few other metabase properties that can also be set, including compression level, but these are the bare minimum.
  • I have been told repeatedly that IISRESET should be sufficient to apply the metabase changes, but I could not get it to work as consistently as manually restarting the IIS Admin Service — YMMV.
  • If all goes well, the nice arrow at the end will point to True.

If you have anything else to add, or have problems with the script, please let me know.

@echo off
set adsutil=C:InetpubAdminScriptsadsutil.vbs
set tcfpath=%windir%IIS Temporary Compressed Files
set extlist=css htm html js txt xml

mkdir "%tcfpath%"

echo Ensure IIS_WPG has Full Control on %tcfpath%

explorer "%tcfpath%.."
pause

cscript.exe %adsutil% set w3svc/Filters/Compression/Parameters/HcDoStaticCompression true
cscript.exe %adsutil% set w3svc/Filters/Compression/Parameters/HcCompressionDirectory "%tcfpath%"
cscript.exe %adsutil% set w3svc/Filters/Compression/DEFLATE/HcFileExtensions %extlist%
cscript.exe %adsutil% set w3svc/Filters/Compression/GZIP/HcFileExtensions %extlist%

echo Restart IIS Admin Service - IISRESET does not seem to work
pause

echo Close Services to continue...
Services.msc

cscript.exe %adsutil% get w3svc/Filters/Compression/Parameters/HcDoStaticCompression

echo Should be True -----------------------------^^

pause
Is Functional Abstraction Too Clever?