Over the course of a week I look at a lot of SharePoint systems. One of the common problems I see with SharePoint 2010 systems too many application pools; both for web apps and service apps. How many is too many, you ask? Microsoft says more than 10 is not supported. Personally, I think all of your service applications should share one app pool, and all of your web applications should share another app pool. Of course there are exceptions to that, but I use the 1 app pool rule as a starting point. I see a lot of farms where each web app has its own service apps, and that’s just unnecessary. In most cases it serves no purpose, and only complicates your farm. Sharing application pools, however, has many benefits. For one, it makes more efficient use of your servers’ RAM. Each application pool is going to consume around 200 MB for overhead. More app pools, more 200 MB chunks chewed up for no reason. Second, all your SharePoint web apps are going to cache roughly the same pieces of code. Not only will all that be duplicated, chewing up more RAM, but each web app will have to take the negative cache hit the first time it tries to load each type of code. If the web apps were sharing an app pool, that negative cache hit would come up less often. Third, we’ve all experience the old, “the first person to hit SharePoint in the morning has to wait a long time for it” situation. That happens because all the app pools recycle in the wee hours of the morning, and the first time someone hits SharePoint its app pool has to wake up and start populating itself with that 200 MB. If every web app has its own app pool, then every web app will experience that. If they all share an app pool, the first hit will start that app pool, and the rest can take advantage of that. Everybody wins, except the members of the IIS App Pool Recyclers Union Local 810.
Service Apps and their Pools
Now that you’re convinced that all your web apps and service apps should all share one pool, what can you to fix farms that were built incorrectly before you stumbled onto this blog post? If you’ve got a lot of service app pools, things are pretty sunny and cheery. There are a bunch of PowerShell cmdlets for creating service app pools, changing them, etc. Most service applications also let you change their app pool at will in its Properties pages, like this:

If you need to consolidate your service app app pools you can choose to put them all on an existing service app (preferably running as sp_serviceapps), or you can create a shiny new one. You can use the box above to change them all to the official app pool. Then you can use PowerShell to remove any of the unused app pools. Here’s an overview of the app pool PowerShell cmdlets:

With service apps this is pretty easy. Unfortunately their web app brethren don’t get the same treatment. For one, we can see while there are four service app pool cmdlets, there are none for web app pools. Fortunately, thanks to good old American sticktoitiveness I found a way to do the same things with web application, and that’s what we’ll cover in this blog.
A Brief History of App Pools
Oh, if web app pools could be as easy to deal with as service app pools. They aren’t, and consolidating unnecessary web app pools is probably more important that consolidating service app pools, because they are often the ones that really soak up the RAM. Let’s walk through consolidating some web app app pools. First let’s see how things are set up now:

This screenshot is pretty tame, as there are only two app pools in play. Most of the time each web app has its own app pool, which is disastrous. In this example I’ll move a web application from the “SharePoint – 80” app pool to the “SharePoint – Default” app pool. Hopefully this app pool is set up well with a good account. It also has a good generic name. These app pools map directly to Application Pools in IIS, and this is where they show up:

We can see our two web app pools there. The highlighted one is the one we’re going to retire. It currently reports three applications, which matches the three web applications shown in PowerShell. We can also see our service app pool as the second entry in the list. It has 15 applications, which map to our service applications. We also have three app pools run as sp_farm. One is the Central Admin app pool, the next is the Security Token Service app pool. It lists it supports seven applications. Five of them are our web applications (four content and central admin), one is the Secure Store service app and the seventh is the SecurityTokenService. The third sp_farm app pool is the Topology Service. For each app pool there is a “View Application” Action on the right. Clicking that shows you each component in IIS that uses that app pool. Each app application pool also maps directly to a W3WP.EXE (World Wide Web Worker Process) process. You can see how much RAM and CPU they’re using in Task Manager:

Since all the app pools show up the same in Task Manager, as w3wp.exe, we need to match them up by Process ID. If the PID column isn’t showing in Task Manager you can enable it View –> Select Columns. Once you have the PID of a W3WP you want to match to an app pool name, run APPCMD.EXE to get a list of the app pools and their PIDs.

We can see that PID 5424 highlighted above is the Service Apps pool.
Moving Right Along
Now that we know all there is to know about app pools, Let’s move our web apps to a new app pool. There doesn’t seem to be any way to do this out of the box, so I had to rely on some PowerShell craziness. I get variables for two web apps. $wa1 has the correct app pool, $wa2 is the one we want to change. The ApplicationPool property is pretty complicated, so instead of trying to construct all that myself, I just copied it from $wa1 to $wa2. Those of you familiar with my blog know the equals sign and I have a much storied past. It was nice to be able to use it correctly this time. Then I updated $wa2 to get the new settings in. The last step was a bit tricky. Just updating the web application wasn’t enough. I had to trigger SharePoint to redo the web app’s settings in IIS. I used the ProvisionGlobally() method for that. That tells SharePoint to rebuild that web app in IIS, which sets its new app pool. Here’s what it looks like:

That’s all there is to it.
After you’ve moved all of the web apps out of an app pool, and its Applications count is 0, you can delete it in IIS. I don’t know of any way to delete it in SharePoint, short of deleting the last web application that is using it. I’m not sure I’d recommend that.
After you consolidate all your app pools you’ll enjoy better performance and hopefully fewer users complaining that SharePoint is slow.
tk