The first call to our API is always extremely slow. For example, below demonstrates the CPU usage and time it takes for the first call to complete:
The first call can take up to 30 seconds and eats almost 100% CPU. Call 2 and 3 take 200ms (as they should). After recycling the application pool, it will do the same thing with the first call.
I've read a bit about IIS "warm-up" and done the following, but nothing has changed:
IIS 8 Application Initialization is installed:
I have the following set in IIS:
- Set Start Mode to AlwaysRunning:
- Set the Recycling Timeout to 0:
- Set the Idle Time-out to 0:
- Set Preload Enabled to true on the site:
I am actually setting these in code in RoleEntryPoint.OnStart()
.
using (var serverManager = new ServerManager())
{
serverManager.ApplicationPoolDefaults.ProcessModel.IdleTimeout = TimeSpan.Zero;
foreach (var application in serverManager.Sites.SelectMany(x => x.Applications))
{
application["preloadEnabled"] = true;
}
foreach (var applicationPool in serverManager.ApplicationPools)
{
applicationPool.AutoStart = true;
applicationPool["startMode"] = "AlwaysRunning";
applicationPool.ProcessModel.IdleTimeout = TimeSpan.Zero;
applicationPool.Recycling.PeriodicRestart.Time = TimeSpan.Zero;
}
serverManager.CommitChanges();
}
I am almost certain that Entity Framework could be the culprit:
We are generating models from around 100 tables in a EDMX model "designer".
We are generating precompiled views generated by EF Power Tools.
The following initialization is running in
Application_Start()
:using (var context = new MyContext()) { context.Database.Initialize(false); }
I don't have these "initialization" problems when debugging.
The following tech is being used:
- .NET 4.5.1
- ASP.NET Web Api 2
- Entity Framework 6.1.1
- IIS 8 (Azure Web Role)
- Unity 3.5
Can anyone provide me with any other ideas or suggestions?
preloadEnabled="true"
in theapplicationHost.config
file for the web application? – afrazierInitialize
, the DB initialization and seeding is executed. But there is no documentation that warranties that the model (views) is loaded into memory. Perhaps (I only suppose it) the model isn't loaded until it's needed. So, you could also run a simple query inside the DB initializer to ensure this to happen. – JotaBe