As I mentioned in my last post, I had to figure out various ways to make my latest project’s ASP.NET application run faster. One of the ways that I was able to get some “free” (i.e. no code changes) performance was to enable HTTP compression on our web server.
While not a new concept, for some reason I really hadn’t researched this too much before recently. I knew that IIS 7, which we aren’t using, had great support for this but didn’t think IIS 6 could support it. After not much Googling I was all setup with HTTP compression and immediately noticed some great results (measurements were done with Fiddler, check it out if you want to debug your HTTP traffic).
This process I’m going to describe can easily be found out on the interwebs. I figured I’d just streamline it a bit, provide some screen shots, and take out all the extra crap that I read to get my ASP.NET site screaming with HTTP compression.
You need to know is that these changes will require you to bounce (restart) IIS in order for them to take effect. So, plan to do this during off hours or set them aside for your next regularly scheduled maintenance window. Don’t just go and tweak all of this on your production web server in the middle of the day. That would be bad!
The first thing you’ll want to do is open up the Internet Information Services (IIS) Manager on the target server. Once in the management console you’ll want to right click on the name of your server and select All Tasks > Backup/Restore Configuration. This will allow you to create a backup of everything in case you screw something up while trying to do all of this.
Luckily I didn’t need to use this but you can never be too careful.
After you save all that you will want to go back to that same server node and right click again. This time you want too bring up the properties for the server instance. From there, click the check box labeled Enabled Direct Metabase Edit.
Enabling this will allow us to later edit the metabase file (XML) directly. This is much easier than trying to run some of the command line utilities that you can use that basically accomplish the same thing. Some may disagree, but I feel like I can change a few values in an XML file way more quickly than trying to get the cryptic syntax right for various IIS script utilities.
Next, expand the local server node and right click on the Web Sites folder to bring up the properties. From there select the Service tab and enable the Compress application files and Compress Static files check boxes.
Optionally, you can change the temporary directory where IIS will store the compressed files (default is %windir%\IIS Temporary Compressed Files) and put a size limitation on this folder. I left both of these options with their default values. I will probably revisit the size constraint option once our site is live and I can watch it for a while. For now, unlimited is fine.
Next, go back up a level in the IIS management console and right click on Web Service Extensions and choose Create a new web service extension (as opposed to Web Sites, which we were just using). Call the new extension HTTP Compression and point it to %windir%\system32\inetsrv\gzip.dll. Finally, before you click OK be sure to check the Set status checkbox so that it is enabled (Allowed). When it’s done you’ll see the new extension listed like this:
The good news is that you have set all of the settings that you need to get HTTP compression working in its most basic form. If you restart IIS (I always use the trusty iisreset command) you will be compressing your HTTP requests right now. The bad news is that the most basic compression won’t do you much good if you’re serving up anything other than Classic ASP pages or static HTML files. The fix for that is to edit that Metabase file that we talked about earlier.
I’m not 100% sure if you really need or want to restart IIS now or not. To be safe I would probably go ahead and do it. When I first went through this process I was pulling information from a few different resources so I did things in more of a step process. You’re getting a step by step list of things that I found over the course of a few different days. So with that said, go ahead and restart IIS to get the compression working.
Now the easy GUI part is over. We’re going to open up the Metabase file and start to change some values in the XML. What you need to do is open up the Metabase.xml file located at %windir%\system32\inetsrv\Metabase.xml in Notepad or some other text editor. Once opened we want to find the sections that look like this (search for compression/deflate):
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. This needs to be set for both the gzip and deflate entries (so you’ll add each extension twice). Like the samples show, you need to put each extension that you add on a new line. Be sure to follow this carefully as I recall reading something that said IIS is very picky about this. Here are the extensions that I added:
- htm (default)
- html (default)
- txt (default)
- asp (default)
- dll (default)
- exe (default)
Finally be sure to set the HcDynamicCompressionLevel values to 9. 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. Everything I read says that 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 tests with 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). I went with 9 to be safe and it seems to have worked out fine for me.
The end result looks like this:
Do another reset of IIS and you’ll be compressing content used by most ASP.NET sites. You can obviously add more extensions to some of the areas if needed. There are a few things like axd fieles that I considered compressing but read that it could cause all kinds of problems. I am going to continue to research this and may do some testing for myself to see if I can potentially add this file type in to my dynamic (script) extension list.
You should know that the process I’ve described here enables compression for all of the sites on your server. If you would like to target only one website or a smaller subset of sites you will need to make some additional changes in the Metabase file in other areas (i.e. IISCompressionSchemes node). I didn’t do that so I am not going to go into detail about that. If that’s something that you want to do it shouldn’t be too hard to find additional information on doing this.
Also, while I stated in the beginning that enabling this was a way to get a “free” performance gain, it’s obviously not free. You’re going to pay the price somewhere. In this case the server will need to do more processing/work now to compress these files before they’re sent down the wire to your users. Based on what I’ve read and what I’ve seen from my testing, IIS 6 is pretty darn efficient with this and as long as your CPU load is under 80% you should be fine to enable this. That obviously will need to be a decision that you make based on the amount of traffic your site gets, the hardware your server has, etc.