This web site uses Azure CDN as a method to cache content (in addition to WordPress’ CDN). I wanted to see how Azure CDN really makes a difference so I created a specific Azure CDN Performance Test to see how it impacts Azure Web Site Performance.
Creating an Azure Web Site and CDN
To test out our application, I created a new Azure Web Site called cachetest. In addition, I created an Azure CDN end point based on this web site. Note: it can take an hour for the Azure CDN to successfully cache all your content.
Designing the Basic Test
I created a very basic web application using the ASP.NET MVC Framework (you can find the files on Github here).
The application displays a simple page that displays a random number and the current date/time. In addition, it has a method called “SomeSlowOperation” which calculates prime numbers using a really bad algorithm from 1 to 100,000. Running the page takes about 10-15 seconds under zero load and produces the following output.
Refreshing the page generates a new random number and updates the date that the page was constructed.
Adding Caching Settings
When you use Azure CDN, you have to make sure you are issuing HTTP Cache Control settings for both static content and dynamic content.
For static content, you can set the cache parameter in the web.config like this:
<clientCache cacheControlMaxAge="1.00:00:00" cacheControlMode="UseMaxAge" />
<validation validateIntegratedModeConfiguration="false" />
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" preCondition="managedHandler" />
This directive will mean any static content (e.g. scripts, CSS files, images, etc.) are cached by the Azure CDN for 1 day.
For dynamic content (e.g. our ASP.NET web page), you need to add HTTP CACHE directives into the page itself. The easiest spot to put this is in the controller’s method like this:
public ActionResult CacheTest()
Response.AddHeader("Cache-Control", "public, max-age=900, s-maxage=900");
CacheTestModel cacheTestModel = new CacheTestModel();
ViewBag.Message = "Cache Testing Page.";
The Response.AddHeader method will add the Cache-Control directives that will be read by Azure CDN to dictate when to expire the page.
NOTE: without these cache directives, Azure CDN caches content for 7 days and once cached there are no tools available to invalidate the cache! Make sure you have the cache directives working before you start accessing the page through Azure CDN.
Running the Test
To run the test, we simply accessed the page through a regular browser through some test VMs running in Azure. We also tested access through my local laptop in Toronto.
Hitting the page directly without going through Azure CDN produces the expected result – each page load takes 10-15 seconds. Hitting the same page once cached by Azure CDN takes milliseconds! However, the results of my tests yield some interesting results in terms of when a page is actually cached:
- It takes 3 hits to the same page before Azure CDN seems to cache the page. The first two loads are slow and reload the page (you can tell because the random number and the dates change). On the third load the page is now served from cache and is very quick (e.g. milliseconds) and the content is now the same on each load.
- Caches seem to be isolated to particular locations. For example, my browser running in Toronto is served cached content after 3 page loads but when I run the same page in a VM in North Central US, there is no cached content and it takes another 3 page loads before that location is serving cached content.
- As a result of the local caches in different locations, the content that is cached can be different if it’s rendered dynamically. For example, here are the results for my browser in Toronto vs. a VM running in the US. Conversely, two VMs running in the same region had the same behavior, e.g. both were served the cached version of the page. It’s not clear where the regions are located and their boundaries.
- If query string is enabled, then each variation of query string follows the same rules as above, e.g. you need to load the exact same URL with the same query string three times before caching seems to take any effect.
Azure CDN will definitely take load off your web server, especially in cases where you have significantly complex or expensive page loads. However, the caching behavior means that Azure CDN may not be caching as expected – each region has its own caching and pages are only cached after being repeatedly hit in the same region.
Once the page is cached, performance is a lot snappier especially for pages that take a long time to process. Make sure you set your cache expiry to be as long as possible to maximize the value of the cache and avoid it being expired.