One of ASP.NET feature that we can use to speed up our application is using IIS Auto-Start Feature. Auto-Start, introduced with IIS 7.5, allows an ASP.NET application deployed to IIS to be available immediately after deployment. In the simplest sense, enabling this feature causes IIS to prime an application as soon as it is deployed removing the warm-up time often required of “cold hits” to a website. In this article we’ll see how we can enable this feature either through IIS Manager or configuration files and even how we can perform more advanced application warm-up routines, such as priming a cache.
Configuring Auto-Start with IIS Manager
Enabling Auto-Start via IIS is actually quite simple, though the settings can be tricky to find the first time.
- Open Internet Information Services (IIS) Manager.
- In the Connections pane, select the Application Pools node, revealing the Application Pools pane in the main view.
- Select the application pool for which you wish to enable Auto-Start.
- Click Advanced Settings…
- Locate the Start Mode option under the General group and set it to AlwaysRunning.
Configuration Auto-Start with applicationHost.config
Enabling Auto-Start using the IIS Manager UI is quick and simple, but tweaking the settings for all of your application pools via the user interface may not be scalable. For example, imagine that you were rolling out your website to a large web server farm and need to automate the configuration of all your application pools.
In this case, we can also enable Auto-Start by tweaking the applicationHost.config file which controls the application domains for all instances running on that server. applicationHost.config can be found at <Windows>\System32\inetsrv\config\applicationHost.config.
Inside of the applicationHost.config file, locate the <applicationPools> node located under<configuration>/<system.applicationHost>. Inside of the <applicationPools> node, locate the entry whose name attribute corresponds to your application pool, and add a startMode attribute with the value of “AlwaysRunning”.
<applicationPools>
<add name="MvcMusicStore" startMode="AlwaysRunning" />
...
</applicationPools>
The addition of the startMode attribute will override the default start mode of “OnDemand“.
Advanced Application Warm Up with Auto-Start
We’ve seen how to work around the “cold-hit” problem that often affects websites running on IIS. However, imagine that early requests to your site can still cause delays, perhaps due to expensive data that has to be retrieved. In these cases you can certainly cache the data after it’s retrieved to make subsequent requests faster, but the unlucky visitor who first makes the request still has to bear the brunt of the work for others.
While in the past it wasn’t unheard of for developers to prime their caches with these expensive data requests in the Application_Start() function of Global.asax.cs, IIS now provides a cleaner way through the use of Auto-Start Providers.
For example, let’s imagine that the home page of your application contains a rather expensive call. In the fact, the call is so expensive that we’ve elected to cache the results improve the performance of subsequent requests. However, this still lays the bulk of the work at the feet of the site’s first visitor.
public ActionResult Index()
{
var albums = HttpRuntime.Cache["TopSellingAlbums"];
if (albums == null)
{
var service = new TopSellingAlbumsService();
albums = service.GetTopFiveSellingAlbums();
HttpRuntime.Cache["TopSellingAlbums"] = albums;
}
return View(albums);
}
While this technique does improve the performance for subsequent visitors, it still lays the bulk of the work at the feet of the site’s first. However, IIS now provides a better place to perform these types of warm-up tasks.
Preload clients, which implement the IProcessHostPreloadClient interface, contain a single method Preload(…) which can be used to cleanly perform these warm-up tasks.
public class MvcMusicStoreApplicationPreloadClient : IProcessHostPreloadClient
{
public void Preload(string[] parameters)
{
var service = new TopSellingAlbumsService();
HttpRuntime.Cache["TopSellingAlbums"] = service.GetTopFiveSellingAlbums();
}
}
However, this class will not be loaded automatically. We need to tell IIS both about the existence of this class as well as which website it applies to. To do this, we’ll need to return to our applicationHost.config file.
First, we’ll need to add an element called <serviceAutoStartProviders> to the<configuration>/<system.applicationHost> node.
<serviceAutoStartProviders>
<add name="MvcMusicStoreAutoStartProvider" type="MvcMusicStore.MvcMusicStoreApplicationPreloadClient, MvcMusicStore" />
</serviceAutoStartProviders>
This element registers our custom preload client with the name MvcMusicStoreAutoStartProvider. Be sure to fully qualify the type name in the type attribute so the assembly loader can locate it.
Finally, we’ll locate the entry for our site under the sites node and register our preload client in our site’s application node.
<site name="MvcMusicStore" id="1" serverAutoStart="true">
<application path="/" applicationPool="MvcMusicStore" serviceAutoStartEnabled="true" serviceAutoStartProvider="MvcMusicStoreAutoStartProvider">
</application>
. . .
</site>
This is done by adding the serviceAutoStartEnabled attribute, set to true, and by adding theserviceAutoStartProvider attribute, set to the name of the serviceAutoStartProvider entry we added in the previous step.
Wrapping Up
With just a few easy steps we’ve ensured that our application is always ready to go when a user a visits. In addition, we’ve also discovered an easy way to offload time intensive operations, such as priming a cold cache, from the first user to the initial startup of the application. With these two tips in hand we’re sure to have a fast and responsive application that our users will rave about.