Analyzing Sitecore Cache Stats with a LINQPad Script

It's important to ensure that your cache sizes in Sitecore are appropriately sized for the load on your site. Too small and the cache will get evicted too often, hurting performance. Too big and you risk wasting server memory.

In this article, I give a quick overview of viewing cache usage using the standard Sitecore tools, before I then show what you can do using my LINQPad script.

Viewing Cache Usage

Sitecore XM\XP provides two options to view your cache usage:

  • an admin page (eg http://yoursite.com/sitecore/admin/cache.aspx

  • cache diagnostics files

The admin page is usually accessible on your CM environment and provides a single snapshot at the current point in time.

Enabling Diagnostics

The LINQPad script uses files generated from diagnostics logging. To enable diagnostics, you typically find the file:

\App_Config\Sitecore\CMS.Core\Sitecore.Diagnostics.config.disabled

and then rename it removing the ".disabled" part leaving you with:

\App_Config\Sitecore\CMS.Core\Sitecore.Diagnostics.config

Caution! This will trigger a restart of the environment!

It is not advisable to leave this enabled permanently as it does incur some performance overhead and disk space.

Viewing Cache Status Files

The default logging interval is 10 minutes, so about 10 minutes after the restart you should start seeing files created in the folder:

\App_Data\diagnostics\health_monitor\cache_status

If you are using an Azure App Service, you can access the folder via the Kudu console and download a zip of all the status files at once. Opening one of the files in a browser reveals something like this:

Things which annoy me here are:

  1. table is not sorted

  2. the Size is not shown in the same units as MaxSize

  3. each file provides just a snapshot of a point in time

This means it's harder to eyeball whether a cache is near its limit without doing the conversion mentally. The script converts all cache size values to bytes internally. It then converts to the configured unit for output, so the CSV shows current and max side by side in the same units.

Cache Tuning Objectives

Our goals when reviewing these files are to:

  • find any caches which are reaching 80% of the maximum size

  • find any caches which are consistently below 50% of the maximum size

For caches which are reaching 80% of maximum size, the recommendation is to increase by 25%.

For those which are consistently below 50% of the maximum size, the recommendation is to reduce by 25%.

Using the script

To avoid having to manually trawl through report files, I have written a LINQPad script which parses the files and aggregates the data producing a summary table of results including min-max-average for count and size and a flag indicating if the cache requires adjustment along with the recommendation e.g. "Increase cache size to 500MB". The complete list of fields output is:

  • Name

  • CountMin (number of items in cache)

  • CountMax

  • CountAverage

  • SizeMin (size in Bytes, KB, MB etc)

  • SizeMax

  • SizeAverage

  • ConfigSizeValue (value defined in config patch file)

  • ConfigSizeUnit (units of value in config patch file e.g. KB, MB etc)

  • NeedsAdjustment (true\false depending on whether cache approaches maximum, or well below)

  • Recommendation (text suggesting what to do eg "Increase cache size to 150MB")

There's one case worth mentioning: if a cache is near a resize threshold but had zero items throughout the capture window, the script won't blindly recommend a resize. Instead it flags it as "Unused during capture window - verify before resizing." This stops the script from telling you to shrink a cache that wasn't exercised during your sampling period. This could easily happen if your capture window missed a particular user flow or scheduled job. It's a nudge to double-check before acting, rather than a hard recommendation either way.

To run the script, download it from the Gist here: CacheStatsAggregation.linq open in LINQPad then hit F5. It prompts for a folder - this should be the folder containing multiple cache status files which you downloaded (multiple files named something like CacheStatus.20260720Z.213238Z.html).

The script creates a subfolder under the directory you selected named "output" which will now contain a file named "cache_status_report.csv" which looks like this:

Viewing Charts in LINQPad

To examine individual caches and explore how their usage varies over time, there is a chart function on the script:

  1. locate the output pane

  2. go to the "Select a Cache" tab

  3. select the cache name from the dropdown (only ones which need adjustment are listed)

  4. switch back to the "Results" tab to see a line chart of the size over time.

The chart includes the maximum cache size (as defined in the Sitecore configs) and also the recommended new cache size.

Iterate

Once you have identified caches which need to be adjusted:

  1. make the changes to the relevant patch configs

  2. deploy your changes (ideally to production)

  3. take another diagnostics snapshot (again, ideally from production and remember to re-enable diagnostics if you disabled it)

  4. analyse the cache usage again using the same process

Repeat this process until your cache levels remain comfortably under the max limits.

Finally, don't forget to turn off diagnostics when you're done.

Wrap Up

Thanks for reading if you got this far. If you have any comments, questions, suggestions or ideas, please drop a comment below.

Thanks!

comments powered by Disqus