While working on a connector for a third-party integration, I was forced to take a nice, long stroll through the underworld of Sitecore Caching. As I progressed, the hardest part to keep straight was what the different caches are for and what the caching lifecycle actually looks like. In this post, I will summarize the notes that I found online and the observations that I made from the code itself on the different Sitecore Caches.
Sitecore Cache Types
Sitecore's caches can be categorized into two groups: Site Caches and Database Caches.
Each site in the solution gets its own cache. This is the HTML Cache, and it's used to cache the rendered presentation components. Making effective use of the site's HTML cache can help to dramatically speed up page load times.
As much as we would all hate to admit it, sometimes deadlines force us to launch with that one really non-performant rendering that makes an excessive number of item requests even though the rendered HTML never really changes. Fortunately, leveraging the HTML cache to help alleviate this performance bottleneck is as simple as checking a box on the rendering or the sublayout.
The Sitecore databases are pretty big, and so are the Items that we retrieve from them. Fortunately, the Sitecore development team outfitted the platform with not one, not two, but THREE different database caches! Every Sitecore database has its own of the following three caches:
- Item Cache
- Data Cache
- Prefetch Cache
The database caches are designed to front-load a lot of the data access work in exchange increased performance after startup, to reduce number of actual requests to the database, and to reduce the number of times that item information needs to be parsed.
Obviously, the database caches are absolutely critical for any enterprise-level Sitecore solution.
The HTML Cache is used to improve the load time of your renderings and sublayouts, by storing the rendered HTML for those components with rendered markup that is not dynamic and does not frequently change.
As previously mentioned, the HTML Cache is incredibly useful for components with low performance on the back-end or for which excessive amounts of item request calls are made. Some common examples of components that are often ideal candidates for caching are the site's Header and Footer. These items typically make very large amounts of repetitive item requests, and the markup for these components usually does not change very often. Worse still, these components are included on (nearly) every page of the site. As such, once the client has completed content entry on these components, it is often a good idea to enable caching on the renderings.
When you cache a rendering or sublayout, it's important to know what is actually being cached. Remember that the rendered HTML of the rendering or sublayout is what's stored in the HTML Cache. In other words, the HTML Cache isn't able to differentiate between renderings and nested renderings; it all just looks like one giant chunk of markup. This means that you do not need to (and should not actually) mark every single rendering and sublayout as cacheable.
The renderings that you plan to reuse in multiple parent renderings should not be marked cacheable, as the markup that they render will change frequently. Consider a site Header, for example. The Header is comprised of a single Header rendering and several Header Navigation Link renderings. Since the markup generated by the Header Navigation Link renderings will change for each link item that is rendered, this rendering should not be cached. However, caching the Header rendering, which only changes on publish (when the cache is cleared) will cache the entire rendered HTML output of the header, including all of the rendered link items.
Like the HTML Cache, the Item Cache does exactly what its name implies: it caches teddy bears! :)
Sitcore.Data.Items.Item class is pretty big. Imagine requesting an object of that type from the database a few hundred times per request and having to parse the object every single time. Thankfully, Sitecore includes the item cache so that this doesn't have to happen!
The Sitecore item cache holds
Sitecore.Data.Items.Item objects so that the
ItemInformation objects don't need to be parsed every single time. If a requested item isn't present in the Item Cache, its
ItemInformation is retrieved from the Data Cache, parsed into a
Sitecore.Data.Items.Item and then stored in the item cache.
The Data Cache is arguably one of the most important performance features in all of Sitecore. The Data Cache is responsible for holding the data that has been retrieved from the database, so that it doesn't need to be retrieved multiple times.
The Data Cache significantly reduces the number of requests that are made to the database, overall. The reason why this is so important is because database requests are one of the most expensive commonly-performed operations on a Sitecore site.
Just like the Item Cache attempts to retrieve data from the Data Cache before going to the database, so too does the Data Cache try to retrieve data from the Prefetch Cache. If the data is not available in the Prefetch cache, it is retrieved from the database and loaded into the Prefetch Cache, first, before being loaded into the Data Cache.
The Prefetch Cache serves a simple purpose: load all of the frequently loaded data up front and hold onto it for later. You can configure the items that are loaded into the Prefetch Cache on startup, and additional items and data will be loaded throughout the application lifetime.
As each piece of data that does not currently exist in the Prefetch Cache is requested, it is first stored in the Prefetch Cache, before going anywhere else.
In his post, Sitecore caching - an overview, Jens Mikkelsen said it best: the "purpose of this cache is [...] to trade longer startup times for faster load times at runtime." I completely agree with this analogy, and you can actually watch how much time is taken to build the Prefetch Cache on startup by opening and continuously refreshing the Sitecore log file.
The Cache Request Life-Cycle
The following diagram depicts the Request Life-Cycle for requesting data in Sitecore through the various Sitecore Caches. The diagram and flow summary were both copied from Jens Mickelsen's article, also linked, above:
- If the item which is requested has presentations which are cached, the HTML from the HTML cache is returned and the request is ended.
- If there isn’t any HTML cached all items needed by the presentation is requested from the item cache.
- If the items aren’t in the item cache it is retrieved from the data cache and parsed into an Sitecore.Data.Items.Item and stored in the item cache.
- If the item isn’t present in the data cache, it is retrieved from the prefetch cache and the ItemInformation is stored in the data cache.
- If the item isn’t in the prefetch cache it is retrieved from the database and stored in the prefetch cache as PrefetchData.
UP NEXT: (Part 2) Getting Started with Sitecore HTML Caching →