Frequently, users ask about the "footprint for IIS6"... usually in reference to mass-hosting since it affects the number of application pools that can be simultaneously running. I know that users have a common misconception that Microsoft loves propagating code bloat... but hey, let's not paint that brush too broadly onto IIS6...

Question:

Hi David,

I'm curious to know how much memory a w3wp.exe process on IIS6 (Win2k3 SP1) should use if only hosting a single ASP application? The behavior I'm observing right now is that about 50mb is allocated to every application pool / site (1 application pool (with a unique identity) per site.)

The global web site configuration has been stripped of all "Application Extensions" except those needed to serve ASP content.

50MB per site/app-pool seems pretty expensive - especially in a hosted environment. I prefer to keep each site in a separate app pool for obvious security reasons. I've already gone over this article (http://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/webapp/iis/appisoa.mspx), followed it's suggestions and gotten no improvement in memory usage. Any suggestions? Will IIS 7 be any better in regards to memory usage?

Answer:

Hmm... I do not know what you have configured to run on IIS6, but my default Windows Server 2003 SP1 installation of IIS6 has w3wp.exe weighing in at about 5MB for memory footprint, which is about an order of magnitude less than what you are seeing. This means that your server is not "clean", and you have configured something else using up 45MB of memory per w3wp.exe...

I am not certain how the URL you referenced implies an improvement in memory usage. That article focuses on how to correctly configure Application Pool properties for the purposes of isolation, which is tangential to the issue of memory consumption. Even if one assumes that the URL shows how to optimize memory usage, it can only optimize IIS memory usage because it is not possible for us to give instructions on how to optimize memory usage of unknown arbitrary user code. Thus, this means that if memory usage did not change after you followed the URL's recommendations, it must be user-configured code that is chewing up the extra memory.

Basically, all your information point to the fact that you are running something on IIS6 that is using a lot of memory per w3wp.exe, and it is not IIS. So, I would not be so quick to ask "Will IIS7 be any better in regards to memory usage" ... because I think that even if we make IIS7 super-optimized to use up 0MB memory per w3wp.exe, you still have w3wp.exe using 45MB of memory per w3wp.exe, and you will still ask "will IIS8 be any better in regards to memory usage". At which point we can only throw up our hands because obviously IIS7 cannot be minimized any further... ;-)

Any Benefits to Stripping "Application Extensions"?

Regarding your stripping of "Application Extensions" to optimize memory usage - that actually improves nothing from a memory-consumption nor performance perspective because:

  • Application Extensions are demand-loaded - IIS6 loads the Application Extension DLL on first request to resources that match its extension
  • IIS actually gives you a "cache ISAPI extensions" checkbox to allow you to control whether IIS caches the loaded Application Extension DLL or not (default is to cache for performance and stability - you only uncheck this on non-production boxes for debugging because it allows you to update ISAPI DLLs while debugging it)

What about from a security perspective?

While stripping "Application Extensions" does remove the CONFIGURATION of Application Extension DLLs , it merely makes resources with those extensions subject to be handled by the IIS Static File Handler instead, which may or may not be what you want. Remember, URLs on IIS has to be handled by *something*. See the following URLs for more details on how IIS handles and executes requests:

So, from a security perspective, if you strip "Application Extensions" to with the intent to prevent such resources from being EXECUTED and DOWNLOADED, you also need to make sure that those resources do NOT have a MIME Type in IIS AND the Windows Registry (The effective MIME Type list in IIS6 is a merge between Windows Registry and IIS configuration).

Compare this against the alternative of doing nothing... merely leaving "Application Extensions" as-is and make sure that the Application Extension DLL is not enabled in Web Service Extensions (this is the default configuration). In this case, the resource never gets served out as a static file because it is still mapped to an Application Extension, and since all Web Service Extensions are disabled by default unless modified by the user, IIS6 will never load the Application Extension DLL nor execute the resource... even if you make a direct request to it.

Of course, the exception here is if you have both .asp and .cer mapped to ASP.DLL and you want .asp to execute but not .cer. In this case, you need to unmap .cer as an Application Extension and if you do not want it to be downloaded, make sure no .cer MIME Type exist.

In other words, stripping "Application Extensions", from my perspective, just buys you a warm-fuzzy feeling with a potential security vulnerability to serve out resources you did not intend to. No, this is nothing new; earlier IIS versions will behave in this exact same way except they did not have Web Service Extension, so they could not prevent Application Extension DLLs from loading - which is a part of the vector that worms like Code Red and Nimda exploited. But, the correct solution there is to change the Application Extension to be mapped to a 404.dll - it is effectively what IIS6 allows, except without needing to load a 404.dll.

This is what we mean with "secure by default". :-) IIS6 defaults are likely to be more functionally secure than you can reconfigure. Of course, we cannot extend this to applications subsequently installed on TOP of IIS6 - we can only hope that they hold themselves to a similarly high bar.

Some Sources of Memory Usage in w3wp.exe

So, I suggest you focus on what non-default changes have been made to this server when you are serving ASP pages. Some thoughts:

  • Is your ASP page using some 3rd party component that is using memory
  • Is there a global.asa that is pulling in 3rd party component that is using memory
  • Do you have ISAPI Filters loaded that is running code that uses up memory
  • Do you have ISAPI Extensions *-scriptmapped that is loading up code that uses up memory. For example, ASP.Net.

//David