Scott Hanselman

Caching in ASP.NET - VaryByParam may need VaryByHeader

November 05, 2005 Comment on this post [5] Posted in ASP.NET | DasBlog | HttpModule
Sponsored By

I was tidying up the blog this evening and adding a Reviews category when I visited one of my own pages and noticed that chunks of content were in German. I literally did a double take.

Then I realized that one of my performance optimizations since the site's been getting slammed was to add this to Permalink.aspx (the page that ultimately services DasBlog's single-post pages, no matter what you see in the URL.)

<%@ OutputCache Duration="1800" VaryByParam="*"%>

What could be wrong with that you ask? The idea was to handle different combinations of input and cache page output as appropriate. However, what input would cause my site to serve me, an anglophone, German?

Well, if a German fellow browsing with his browser's Accept-Language header set to anything like "de-DE" and he happened to be the FIRST guy to visit a specific page before it was cached, given the directive above, the page would be cached as it was shown to him. DasBlog will generate most non-content text in the requested language.

Ah! So I needed to:

<%@ OutputCache Duration="1800" VaryByParam="*" VaryByHeader="Accept-Language" %>

Problem solved.

NOTE: I do use HttpCompression and some folks add Accept-Encoding to the VaryByHeader, but the HttpModule I use adds that programatically so everyone gets what they expect. All this caching DOES add up to memory. If someone visted every page in my site at least once with every possible language value, along with HttpCompression on in their browers, then again with HttpCompression off, my Web Server would have to hold a least numOfPages*2*numOfLanguages cached versions of pages.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
November 06, 2005 7:44
It would eat up 2*numOfPages*numOfLanguages -- until the system sensed memory pressure at which time it would start throwing out cached objects like nobody's business.
November 06, 2005 15:00
November 07, 2005 7:50
The whole point of using the ASP.NET Cache is that it will manage the memory usage for you. Just recently I started to place DataSets into the Cache and forcing it to hold it in the Cache until the expiration. So far so good, but I would like to know exactly how much memory is being used by the Cache at any moment. Got any idea how to measure that?
November 07, 2005 17:41
Let me piggy back on Brennan's question and leave another one. How do we know how much memory is being used by an individual ASP.NET AppDomain ? I have a few applications running in a server and one of them seems to have a memory consumption problem...We are trying to identify which but we didn't seem to find an easy way to do so (no, running each app in its own process is not an option at this time)
November 07, 2005 19:58
Sergio, I am not sure about by domain, but I use this line to log memory usage before and after loading the large datasets.

logger.Info("TotalMemory (before) : " + (System.GC.GetTotalMemory(True) / 1024).ToString)

It seems to indicate I jump from 2mb to 5mb when loading all one dataset, which is tolerable with 4gb of total memory. :)

I still had to force it to keep the object in the Cache until expiration because it kept kicking it out. It claimed it was not used enough, but I think any object over a certain size does not stick around long. I even have the Cache settings allowing up to 50% of memory.

There are also other memory related properties on the GC object, but I have not dug into it enough to determine if I can isolate usage by domain or even object. But managed code may not expose that level of detail.

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.