This topic explains how to perform a "warmup" of your DXP site when it scales up or out and before new code is deployed to production. Warmup is the process whereby a Web App gets hit with requests, such as pre-populating in-memory cache before it starts to receive production traffic. This is needed to make new code deployments to production and scaling up/out as seamless as possible.
Default behavior
Optimizely's deployment automation engine attempts to configure a warmup section automatically during deployments by...
- Issuing a web request to the start page.
- Parsing the resulting HTML output to find all relative links on the site's start page.
- Automatically transforming the web.config to include these links in the <applicationInitialization> section.
This is done for each unique hostname that was bound to the site.
The application initialization engine accepts any response from the site (see How it works) including non "200 OK" responses, so a simple .aspx page is added to the site, which ensures that the site gets at least 90 seconds of warmup time before it starts receiving live traffic. The delay is only applied to requests originating from localhost, so it does not affect end user traffic. This page stabilizes scale-outs in scenarios where a new instance might throw a few errors before it's completely warmed up.
The EpiserverDXCWarmupDelay.aspx file is added to the root directory of the Web App. It is called once after the start page of domains that are bound to the site have received a request, and before other pages on the site receive any requests.
The automatic creation of the <applicationInitialization> section (including the creation of EpiserverDXCWarmupDelay.aspx) only occurs if the section does not exist in the web.config file (through transformation or otherwise).
How it works
To warmup the application, application initialization (a built-in feature of IIS) is used by specifying an <applicationInitialization> section in web.config that contains all the paths that needs to be warmed up. The <applicationInitialization> section is placed inside the <system.webServer> configuration section.
The deployment engine automatically configures the hostname, which is used for the request in case different paths or different domains/languages need to be initialized. The request reaches the app from localhost (within each individual instance).
Note: If you decide to create this section yourself, you also need to configure the hostname to use. See Customize your warmup behavior.)
The following example shows a confíguration that warms up the root and an About us page for two languages.
Note: It is not allowed to add duplicate values for the initializationPage attribute. However, a query-string can be added as a workaround if the paths are the same for the different hostnames, like the root-page link in the following example. If you choose to configure this yourself, be sure not to use anything your application will interact with.
<system.webServer>
<applicationInitialization doAppInitAfterRestart="true">
<add initializationPage="/"
hostName="www.optimizely.com"/>
<add initializationPage="/?HostnameToWarmup=www.episerver.se"
hostName="www.optimizely.se"/>
<add initializationPage="/about-us"
hostName="www.optimizely.com"/>
<add initializationPage="/om-oss"
hostName="www.optimizely.se"/>
</applicationInitialization>
<system.webServer>
The requests are sent in a sequential manner starting from the top, waiting on each request until it receives a response.
Note: Any response from the site is accepted, even if it is not a "200 OK" response.
Customize your warmup behavior
While not recommended, you can create a custom <applicationInitialization> section, such as when you need to warm up paths that are not included in the default configuration created by the deployment flow (see Default behavior). Be sure to add this in all your environments, or at least to Preproduction and Production.
You probably want to specify a hostname for the warmup requests, so use a configuration transform to set this for different environments.
Because Optimizely adds this section automatically during deployments if you have not added it yourself, make sure that you clear the <applicationInitialization> section before adding your links if you only add the section to your production environment through configuration transform (see below).
The following sample configuration transform file content is based on the previous example.
Note: The "Remove" transform for the <applicationInitialization> section (row 3) to remove any existing <applicationInitialization> sections from the Integration/Preproduction environments, then adds the new one.
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer xdt:Transform="InsertIfMissing">
<applicationInitialization xdt:Transform="Remove" />
<applicationInitialization xdt:Transform="InsertIfMissing" doAppInitAfterRestart="true">
<add initializationPage="/"
hostName="www.optimizely.com"
xdt:Transform="InsertIfMissing" />
<!-- Add a call to a "warmup delay page" if you have one -->
<add initializationPage="/EpiserverDXCWarmupDelay.aspx"
hostName="www.optimizely.com"
xdt:Transform="InsertIfMissing" />
<add initializationPage="/?HostnameToWarmup=www.episerver.se"
hostName="www.optimizely.se"
xdt:Transform="InsertIfMissing" />
<add initializationPage="/about-us"
hostName="www.optimizely.com"
xdt:Transform="InsertIfMissing" />
<add initializationPage="/om-oss"
hostName="www.optimizely.se"
xdt:Transform="InsertIfMissing" />
</applicationInitialization>
</system.webServer>
</configuration>
You also should add a line to web.config in the <applicationInitialization> section to call a page like the EpiserverDXCWarmupDelay.aspx page that the deployment engine would otherwise create (see Default Behavior). The contents of the page that the deployment engine currently creates is:
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Net" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%
if (Request.IsLocal)
{
var WarmupDelay = 90000;
var qWarmupDelay = Request.QueryString["WarmupDelay"];
if (!string.IsNullOrEmpty(qWarmupDelay))
{
WarmupDelay = int.Parse(qWarmupDelay);
}
System.Threading.Thread.Sleep(WarmupDelay);
Response.StatusCode = 200;
this.Title = "Delay finished";
}
else
{
this.Title = "Page not found";
Response.StatusCode = 404;
}
%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title><%=this.Title %></title>
</head>
<body>
</body>
</html>
The warmup requests are invoked sequentially from top-down, so you should place a single call to your .aspx file after the first request is made to the start page of the hostnames so that it has some time to warmup in case the first one would fail or timeout before it continues; like in the following example.
Note: You should replace the www.optimizely.com and www.optimizely.se with your own hostname.
<configuration>
<system.webServer>
<applicationInitialization doAppInitAfterRestart="true">
<!-- Make calls to the hostnames you want to warmup once -->
<add initializationPage="/?HostnameToWarmup=www.episerver.com&FirstRequestBeforeDelay=True"
hostName="www.optimizely.com"/>
<add initializationPage="/?HostnameToWarmup=www.episerver.se&FirstRequestBeforeDelay=True"
hostName="www.optimizely.se"/>
<!-- Add a single call to the "warmup delay page" -->
<add initializationPage="/EpiserverDXCWarmupDelay.aspx?HostnameToWarmup=www.optimizely.com"
hostName="www.optimizely.com"/>
<!-- Continue with the warmup -->
<add initializationPage="/?HostnameToWarmup=www.episerver.com"
hostName="www.optimizely.com"/>
<add initializationPage="/company/?HostnameToWarmup=www.episerver.com"
hostName="www.optimizely.com"/>
<add initializationPage="/?HostnameToWarmup=www.episerver.se"
hostName="www.optimizely.se"/>
<add initializationPage="/om/foretaget/om-oss/?HostnameToWarmup=www.episerver.se"
hostName="www.optimizely.se"/>
</applicationInitialization>
</system.webServer>
</configuration>
Related topics
- How to warm up Azure Web App during deployment slots swap
- Scale up an app in Azure (Microsoft)
- IIS 8.0 Application Initialization (Microsoft)
- Web application warmup during DXP deployments
Last updated: Sep 28, 2021