Recently I had some time to look into the built-in HTTP compression abilities that IIS6 has. There seemed to be too much incorrect/misleading information floating around on this subject, especially about things like needing “Web Service Extension” and about dynamic compression not working without enabling static compression and so on, so this is me trying to clear things up a bit.
I was impressed to find that IIS6 is very much capable in handling compression than what meets the eye. So don’t be deceived by the IIS management GUI that shows only 2 checkboxes for configuring HTTP compression; it is nothing but a hint of what can be done.
In order to compress the response IIS needs to know that the client making the request knows how to uncompress, and what schemes the client understands. So, when we make a request for a web page, our browser needs to take the initiative and tell the web server the types of compressions schemes it understands and knows how to uncompress. This is done via a header such as ‘Accept-Encoding: gzip’ [or 'Accept-Encoding: gzip,deflate' if it supports both gzip and deflate and so on.]. If the browser does not tell IIS this, IIS will only send the raw files as they are. It’s the same for any client application that requests for content from a web server.
Assuming a request has been made from a client that supports compression, here is a simplified version of what happens in IIS.
If the requested page was for dynamic content:
IIS compresses the response and sends the compressed response to the client if the following are true
- If ’Compress application files‘ is enabled [HcDoDynamicCompression="TRUE" at server level or DoDynamicCompression="TRUE" at file/folder level]
- If IIS is able to compress the requested file type using the particular compression scheme the client supports ['HcScriptFileExtensions']
It’s also important to note that a copy of the compressed file will not be cached, so the compression has to take place for each request which costs CPU resources of the server.
If the request for static content:
IIS will send a compressed responce only if the following are true
- If ’Compress static files‘ is enabled [HcDoDynamicCompression="TRUE" at server level or DoStaticCompression="TRUE" at file/folder level]
- If IIS is able to compress the requested file type using the particular compression scheme the client supports ['HcFileExtensions']
- A valid compressed version of the requested file is already available in the ‘Temporary directory‘ [HcCompressionDirectory].
If a valid compressed version of the requested file is not available, IIS will send a uncompressed version of the requested file to the client, after which it will check if the compresssion scheme is to compress static content on demand [HcDoOnDemandCompression="TRUE"]. If it is, IIS will start a background thread to compresses the requested file and store in the ‘Temporary directory‘ to serve for future requests.
Now let’s look at how we can configure all the stuff we talked about above. We can’t do much with the GUI we have got with IIS6 for configuring compression.

GUI for the IIS6 HTTP compression configuration
[Web sites -> Properties -> Service tab]
This means that we’ll need to get into the configuration settings inside the Metabase.xml file located at “%windir%\system32\inetsrv\Metabase.xml” to get compression working properly.
There are a couple of ways to edit this file; we could use the adsutil.vbs, or directly open the file in a text editor and edit it. However, before directly editing this file while IIS is running, we have to make sure that we’ve enabled direct metabase edit.
Like we talked about earlier, the client must first let the server know what compression methods its cable of handling, if the server also knows how to compress in a method that the client understands compression can happen. IIS by default supports both gzip and deflate compression schemes.
The following nodes in the Metabase.xml file is where you can configure how each of these compression schemes work.
<IIsCompressionScheme Location =”/LM/W3SVC/Filters/Compression/deflate”
HcCompressionDll=”%windir%\system32\inetsrv\gzip.dll”
HcCreateFlags=”0″
HcDoDynamicCompression=”TRUE”
HcDoOnDemandCompression=”TRUE”
HcDoStaticCompression=”FALSE”
HcDynamicCompressionLevel=”0″
HcFileExtensions=”htm
html
txt”
HcOnDemandCompLevel=”10″
HcPriority=”1″
HcScriptFileExtensions=”asp
dll
exe”
>
</IIsCompressionScheme>
<IIsCompressionScheme Location =”/LM/W3SVC/Filters/Compression/gzip”
HcCompressionDll=”%windir%\system32\inetsrv\gzip.dll”
HcCreateFlags=”1″
HcDoDynamicCompression=”TRUE”
HcDoOnDemandCompression=”TRUE”
HcDoStaticCompression=”TRUE”
HcDynamicCompressionLevel=”0″
HcFileExtensions=”htm
html
txt”
HcOnDemandCompLevel=”10″
HcPriority=”1″
HcScriptFileExtensions=”asp
dll
exe”
>
</IIsCompressionScheme>
We need to tell the types of extensions that each scheme is to support and compress. The static types need to go under the ‘HcFileExtensions‘ and the dynamic under ‘HcScriptFileExtensions‘. You’d probably want to get aspx, and asmx extensions also under ‘HcScriptFileExtensions‘ in addition to the defaults. xml, css and even consider adding ’deploy’ files if you have clickOnce under the ‘HcFileExtensions‘. We need to add this for both gzip and deflate compression schemes (or you could add it to only one if you don’t want a particular compression scheme to support that extension.
If you’d like to use the adsutil.vbs to set these values here is an example to add static file types css, xml, htm, and txt to the gzip compression scheme:
cscript adsutil.vbs set /w3svc/filters/compression/gzip/HcFileExtensions “css” “xml” “htm” “txt”
to view the change:
cscript adsutil.vbs get /w3svc/filters/compression/gzip/HcFileExtensions
The level of compression for dynamic content is set to 0 by default. This could be increased to a maximum of 10 depending on your available CPU resources. Generally setting it to 10 is bad; in most cases it will have a negative impact on your throughput. This is something you’d need to do some test to figure out what works best for you. It’s also worth noting that setting it to 0 does not mean no compression, it just is a lower compression (which also means it will be the fastest).
Now that we’ve got the two compression methods configured let’s take a look at the ’IIsCompressionSchemes‘ node, this is what basically sets up the server-wide HTTP compression configuration settings.
<IIsCompressionSchemes Location =”/LM/W3SVC/Filters/Compression/Parameters”
HcCacheControlHeader=”max-age=86400″
HcCompressionBufferSize=”8192″
HcCompressionDirectory=”%windir%\IIS Temporary Compressed Files”
HcDoDiskSpaceLimiting=”FALSE”
HcDoDynamicCompression=”FALSE”
HcDoOnDemandCompression=”TRUE”
HcDoStaticCompression=”FALSE”
HcExpiresHeader=”Wed, 01 Jan 1997 12:00:00 GMT”
HcFilesDeletedPerDiskFree=”256″
HcIoBufferSize=”8192″
HcMaxDiskSpaceUsage=”100000000″
HcMaxQueueLength=”1000″
HcMinFileSizeForComp=”1″
HcNoCompressionForHttp10=”TRUE”
HcNoCompressionForProxies=”TRUE”
HcNoCompressionForRange=”FALSE”
HcSendCacheHeaders=”FALSE”
>
</IIsCompressionSchemes>
If you’d like to enable compression server wide, we can change HcDoDynamicCompression=”FALSE” to “TRUE” for dynamic content and HcDoStaticCompression=”FALSE” to “TRUE” for static content. However, if we don’t want to enable http compression server wide, we simply leave these as ”FALSE” and add a property DoStaticCompression=”TRUE” and/or DoDynamicCompression=”TRUE” to the specific file or folder properties in the metabase where you’d like to enable compression.
For example if you we want to enable http compression on a virtual directory called “CompressMe” under your “Default Web Site”, we’d simply locate the following node in theMetabase.xml file:
<IIsWebVirtualDir Location =”/LM/W3SVC/1/ROOT/CompressMe”
AccessFlags=”AccessRead”
DirBrowseFlags=”DirBrowseShowDate | DirBrowseShowTime | DirBrowseShowSize | DirBrowseShowExtension | DirBrowseShowLongDate | EnableDefaultDoc”
Path=”C:\Inetpub\CompressMe”
>
and add the property DoStaticCompression=”TRUE” as follows:
<IIsWebVirtualDir Location =”/LM/W3SVC/1/ROOT/CompressMe”
AccessFlags=”AccessRead”
DirBrowseFlags=”DirBrowseShowDate | DirBrowseShowTime | DirBrowseShowSize | DirBrowseShowExtension | DirBrowseShowLongDate | EnableDefaultDoc”
DoStaticCompression=”TRUE”
Path=”C:\Inetpub\CompressMe”
>
If a node does not exist for the folder you’re trying to configure, you could simply add a node manually, or make IIS add it for you using a small trick. What we do is change a property for the required file/folder and then undo the change. For example for a folder we could just enable “Directory browsing” and then disable it again. Restart IIS and it would have created a node for you in the Metabase.xml file.
Well that should get compression to work, but as you can see lots of other configuration parameters that you could configure to get the best out of your server.
A lot of the above has changed with IIS7. We can see things like static compression being enabled by default!
Happy compressing!
Lovely. Fabulous article and very very useful.