Performance Tuning and Optimization of EPiServer

There are many factors to look at when you want to tune the performance of your EPiServer site. This is the first post about common pitfalls and how to optimize EPiServer for performance.

EPiServer and Memory

First thing to check is that you have enough memory. EPiServer needs a lot of memory to cache the PageData object for each of all active pages on the site. The larger site (more pages) you have, the more memory you will need.

The DataFactory class will first look if the requested page or list of pages is in the cache when you call GetPage() or GetChildren(). If it is not in the cache, the page or list will be loaded from the database and added to the cache. The default implementation (read more about pluggable runtime cache) uses ASP.NET’s built-in public cache to store pages and lists in memory.

EPiServer Database Cache UsageThe public cache in ASP.NET is also used to store other data in addition to EPiServer PageData and Lists. Periodically ASP.NET will use a Least Recently Used (LRU) algorithm to scavenge the cache for more space. If the memory pressure is very high the lifetime of cached items can be very short or even zero (not added at all). This is not good for EPiServer’s performance.

It is easy to see what’s inside your cache:

protected void Page_Load(object sender, EventArgs e) 
    foreach (DictionaryEntry d in this.Cache) 
        Response.Write(" - "); 

A very good indicator if Memory is an issue is to look at some statistics from the DataFactory class. You can see the Cache hit rate if you go to admin mode. It should be close to 100% or maybe a few percent below. (It is normal that it drops to zero when you restart the site but it should climb fast.) A constant low value is one indicator that you need more memory because PageData objects are thrown out of the cache and then they must be reloaded from the database.Add EPiServer Performance CountersYou can also see the Cache Hit Ratio (and some other counters) through Windows Performance Monitor. This is a good value to monitor in a hosting environment and add an alert when the value becomes to low.

ASP.NET Worker Process / Application Pool

The maximum memory ASP.NET allows a worker process to consume before it is recycled is by default 60% of the total system memory. Read more about memoryLimit tag.


Default Application Pool – Do not use it and do NOT delete it (even if you plan to never use it). Create your own pool instead but not create one pool for each site on the web server. Instead consolidate your applications into one pool and only use a separate pool for troublesome web applications. You must have separate pools for ASP.NET 1.1 and 2.0 applications though.

Application Pool RecyclingYou can also configure the application pool to recycle if it consumes to much memory. If you worker process constantly recycles you need to find out why because EPiServer will always be a little bit sluggish after a restart (before data is cached again). You also loose all in-process session data when the process restarts which is an issue of its own.

Settings: I recommend that you uncheck “Recycle worker process (in minutes)” and use “Recycle worker process at the following times” instead.

Application Pool Performance You should also uncheck “Shutdown worker process after being idle”. This is very important for EPiServer sites that has a low traffic (for example during the night).

Do not use Web Garden unless you know what you are doing. It will require double memory for the cache and out of process state-handling. If you change the number of worker processes from 1 to 2 it is like having two web servers on the same box with IIS acting like load balancer. (It is a cheap way in a development environment to test how you application will behave in a farm with load balancing.)

MSSQL Server and EPiServer

MSSQL Server Properties MemoryIts a best practice to have two machines, one for the web server and one for the database. But sometimes you have to run the database on the same machine as the web server. If you do, it is important to remeber that the MSSQL Server competes with the Web Server for resources like memory. You should always limit the amount of memory the database can use because it is better for EPiServer to have data cached in the web application than in the database.

Usually the usage of the database is low (around 5% CPU) in EPiServer scenarios because EPiServer tries to cache what it needs in the web application. If you have a higher usage of the database this can be an indication of that caching does not work as it should in the web application but it could also indicate that you do something else wrong. (More about database issues in a later post.)

Other processes

Finally, do not forget to have use the ordinary task manager to check if you have other processes that compete for the memory on your web server.