Understanding Once-Per-Session Cache Validation

Last year, I wrote about the IE9 improvements in heuristic expiration, which apply when a server fails to specify how long a cached resource should be treated as fresh. Heuristic Expiration works by calculating an implicit freshness lifetime from the Last-Modified timestamp on the cached resource and the timestamp at which the resource was downloaded from the server.

However, the Heuristic Expiration calculation only applies when the user’s Check for newer versions of stored pages option (a.k.a. “SyncMode“) inside Tools > Internet Options > Browsing History Settings is set to Automatically.


As mentioned, the heuristic expiration feature relies upon the server providing a Last-Modified timestamp on the response. If the server fails to provide such a timestamp, then Internet Explorer will fall back to its Once-Per-Session syncmode for that resource. A user may elect to use Once-Per-Session syncmode (for all resources) in lieu of Heuristic Expiration by selecting the Every time I start Internet Explorer radio button.

WinINET keeps track of when the current process has started in a variable called SessionStartTime. Every entry in the WinINET cache has a LastSyncTime. If the cache syncmode is Once-Per-Session, when WinINET is deciding whether or not to reuse a resource of unknown freshness, it compares the resource’s LastSyncTime to the process’ SessionStartTime. If the LastSyncTime is earlier than the SessionStartTime, WinINET will not immediately reuse the cached version and will instead make a network request to the server to check for freshness, potentially downloading an updated version of the resource in the process.

Once-Per-Session syncmode has a few non-obvious subtleties.

  1. To establish an upper-bound on reuse, WinINET will also perform revalidation if the current time is more than 12 hours after the LastSyncTime.
  2. In any version of IE, if a page’s JavaScript executes the ClearAuthenticationCache command, that invokes the INTERNET_OPTION_END_BROWSER_SESSION operation in WinINET. Internally, the EndBrowserSession option (among many other operations) invokes the INTERNET_OPTION_RESET_URLCACHE_SESSION operation, which sets the current process’ SessionStartTime to the current time. So, if any page invokes this API, any “Once per session” resources will be revalidated before being reused by the current process.
  3. If INTERNET_FLAG_HYPERLINK is present on the request, and a cached response doesn’t have a Last-Modified value set, then WinINET will always revalidate the cached resource before reuse, ignoring the Once-Per-Session rule. IE9 uses FLAG_HYPERLINK (via BINDF_HYPERLINK) when performing most document (e.g. top-level or frame) downloads.
  4. In Internet Explorer 8, simply opening a new tab (which creates a LCIE Tab process) would reset the SessionStartTime for all other tabs in the current Browser Session. This behavior hurt performance, and was corrected in IE9. In IE9, every new tab process in a Browser Session will inherit the original SessionStartTime for the browser session, eliminating this performance penalty.

So, what does this gobbledygook all mean to you, the web developer? Avoid the confusion and unpredictability of cache heuristics and specify an explicit expiration time!



Comments (7)

  1. jdew@greyfence.com says:

    I have a slide viewer application which creates multiple iframes in IE in kiosk mode and cycles through different content (graphics, flash, wmv's using embedded wmp) in each one.  The application is used for low priced digital signs.

    One of the features I've been able to offer is that if the internet connection dropped (as it often can when digital signs are placed far from the wifi AP) IE would be switched to offline mode and everything would continue playing from cache.  When the network connection is restored IE is put back into online mode and it can update its content.  The application was originally developed for IE6 and worked very well.

    But, with IE9 I've run into a couple of snags with this.  

    Number 1:  wmv content will not play from cache at all.  Even if the wmv's are in the cache, if IE9 is put into offline mode it will not play them.  It appears to change the protocol from http:// to mms:// but even after dynamically updating the protocol, it will not play them.

    Question: how can I get it to play wmv files from cache?

    Number 2:  IE9 puts itself into 'online' mode when it is launched with a URL.  I've purposely set the GlobalOffline flag to force it to play from cache but it switches it back into online mode on its own.

    Question: how I can keep IE9 from going online automatically on launch?

    Thanks for your exellent articles.  The information I've gleaned from this article and the previous one on caching has been very helpful in improving my application.

  2. EricLaw says:


    #1: Video URLs are converted from http:// to mms:// by the Windows Media Player ActiveX control. IE itself doesn't participate in or control that behavior. I'm afraid I have no idea why these won't play from the cache.

    #2: As far as I know, there's no supported way to opt IE out of the "go online automatically" behavior which hits if you try to navigate to a resource which is not already cached locally. (I'll verify and update this remark if I turn up anything different). If you ensure that all resources are cached properly (e.g. nothing is no-cache, Vary: *, etc) then you shouldn't hit the "Go online" behavior at all.

    More generally, you'll probably want to migrate your application away from running IE in Kiosk mode and instead host a Web Browser Control instance which then hosts your content. This will give you far more control over the behavior and create a more stable platform which is less likely to change between versions.

  3. jdew@greyfence.com says:

    Thanks for your quick reply!

    #1:  Is there a blog / forum hereabouts where I can ask the Media Player team about that?  Not being able to play wmv's from the cache really cuts down on the usefulness of our application.

    #2:  It definitely behaves more reliably if I do the Web Browser Control hosting route I'll continue working in that direction from now on.   As I'll show in a minute, I do have no-cache, etc set.

    Updated jpg's are not being detected reliably unless I set some headers on the server.  The images can be updated as often as once a minute (they may have the time imprinted on them) so it's important that the current one is being displayed.  

    I've tried all the different 'Check for newer versions of stored pages' options and the best combination I've found is to set the 'Check for newer…' to 'Automatic'  and to add this to my Apache configuration:

    <FilesMatch ".(jpg|cgi|swf)$">

    Header set Cache-Control "max-age=0, must-revalidate"

    Header set last-modified "Sun Jul 18 00:32:50 GMT 2004"

    ExpiresActive on

    ExpiresDefault "access plus 0 minutes"


    With this combination the jpgs are being detected when they change and still play from cache when put offline.  

    Prior to IE8 I could set 'Every time I visit the webpage' and it would detect the changed images with no changes on the server.

    Is there some other way I could configure things to make IE detect changes reliably?

  4. EricLaw [MSFT] says:

    @dunfield: You should read blogs.msdn.com/…/caching-improvements-in-internet-explorer-9.aspx. "Cache-Control: max-age=0, mustrevalidate" literally means "You may not re-use this element without validating it with the server, and you must not re-use the cached copy if you cannot reach the server, say, because you're offline."

  5. jdew@greyfence.com says:

    @EricLaw : I have read your previous article.  I've removed the conditions from my Apache install and now again have intermittent issues with the images not being updated in a timely fashion.  I can't yet narrow down the conditions.

    Where can I contact the Media Player team to ask about playing files from the cache when offline.  This is a critical issue and am stuck since I don't see a way to downgrade WMP to a previous version in Win7.


  6. gkiras says:

    Hi Eric,

    I am using php in IIS (win2008_32bit, IIS7 with SSL)

    I have session problems with IE. When i browse my site with Chrome or Firefox i can get Session variables that i set. But with IE, i cant take any session variables. What can i do?

    Already I posted a topic about it in IIS forum : forums.iis.net/…/1183200.aspx

    Thanks for your help.

  7. EricLaw says:

    @gkiras: Email me using the contact link. The link you posted to your site is broken, and your question is about cookies, not caching.