I'm curious if the Umbraco CMS framework has built-in caching mechanism for its various content/data.
Most of the data managed by the Umbraco CMS I consider to be domain data. They don't change frequently or very often at run-time. Unless a content editor publishes a new content, it doesn't make sense for site traffic to continually hit the underlying Umbraco CMS data storage. It makes more sense for the data access layer of the framework to cache the content data whereby the content cache gets refreshed when a content publish occurs.
Does the mechanism I describe above exist already? If not where/how one introduce such?
Umbraco has something like you described out of the box.
When you are using UmbracoHelper for retrieving data from Umbraco, it doesn't make request to db, it gets data from XML cache, which is stored in /App_Data/umbraco.config
Another useful way to use cache with Umbraco, is to use Html.CachedPartial Razor helper. I like this helper very much, because you can make cacheble big parts of your site, like navigation, footer, side blocks.
Alex has provided excellent information, which should suffice for most needs. However, if you want to programatically cache data directly into memory you can also use the Umbraco service caches where accessible from the following class:
Thanks for this question Dylan and for the answers Alex and Dan. Sometimes getting down to the basic questions are really interesting and useful.
So, Alex, when you say "When you are using UmbracoHelper for retrieving data from Umbraco, it doesn't make request to db, it gets data from XML cache" does that mean retrieving data in other ways (e.g., Model.Content.GetPropertyValue("myField")) does hit the db? Does that mean using UmbracoHelper is preferable most of the time?
Regarding partial views and caching, the docs say this:
You don't normally need to cache the output of Partial views, just
like you don't normally need to cache the output of User Controls, but
there are times when this is necessary.
I took that to mean that partials are usually cached anyway, unless you're doing something weird which means you have to force caching. What does "You don't normally need to cache the output of partial views" really mean, and what are the circumstances under which it would be necessary to use Html.CachedPartial?
No, using Model.Content.GetPropertyValue("myField") will NOT hit the DB.
Neither will @Umbraco.Field("myProperty") or @Umbraco.TypedContent(1234). Nor will any queries such Mode.Content.Children() or Model.Content.Descendants().Where(c => c.IsVisible() && c.DocumentTypeAlias == "MyDocTypeAlias")
Basically, anything that returns an instance of IPublishedContent doesn't hit the database. So all your standard querying you would normally use retrieve values from the cache (currently an XML Cache, but this may change in future). These are all "read-only" queries.
You only really hit the DB in Umbraco if you use the ContentService methods which are read/write. But generally you only use these if you need to access unpublished content or wish to create new content programatically.
As for Partial caching...
I'm not sure I'd agree with the docs when they say:
"You don't normally need to cache the output of Partial views..."
Perhaps they mean that just retrieving content in Umbraco is fast and so doesn't really benefit too much from caching? But I'd still argue that if your content isn't changing much then it would benefit from partial caching. I usually cache all content on the home page and in things like the header and footer since this won't change often. The cache is automatically invalidated whenever any content is published, so you don't need to worry about "stale" content.
Just don't cache stuff that is truly dynamic, such as forms, and be careful to know when to cache globally and when to cache by page.
The cache is automatically "bust" every time you publish any page in your site. So in the vast majority of cases you don't need to worry about it - it just "works".
Note that when Umbraco is in debug mode (ie. debug is set in compilation in web.config) then caching is turned off - it only kicks-in when debug is turned off. This makes dev easier as you don't need to worry about dealing with cached content during development.
Hypothetically, if I put my Umbraco application behind a load balancer in 5 different containers, and lets say by default the XML Cache is stored in each container, how can I make sure that the XML Cache is synced and properly invalidated across the containers? Is there some configuration we can tamper with?
Umbraco data caching?
I'm curious if the Umbraco CMS framework has built-in caching mechanism for its various content/data.
Most of the data managed by the Umbraco CMS I consider to be domain data. They don't change frequently or very often at run-time. Unless a content editor publishes a new content, it doesn't make sense for site traffic to continually hit the underlying Umbraco CMS data storage. It makes more sense for the data access layer of the framework to cache the content data whereby the content cache gets refreshed when a content publish occurs.
Does the mechanism I describe above exist already? If not where/how one introduce such?
Hi Dylan,
Umbraco has something like you described out of the box. When you are using UmbracoHelper for retrieving data from Umbraco, it doesn't make request to db, it gets data from XML cache, which is stored in /App_Data/umbraco.config
Read more about UmbracoHelper: https://our.umbraco.org/documentation/Reference/Querying/UmbracoHelper/
Another useful way to use cache with Umbraco, is to use Html.CachedPartial Razor helper. I like this helper very much, because you can make cacheble big parts of your site, like navigation, footer, side blocks.
Read more about CachedPartials: https://our.umbraco.org/documentation/Reference/Templating/Mvc/partial-views
Thanks, Alex
Alex has provided excellent information, which should suffice for most needs. However, if you want to programatically cache data directly into memory you can also use the Umbraco service caches where accessible from the following class:
Thanks for this question Dylan and for the answers Alex and Dan. Sometimes getting down to the basic questions are really interesting and useful.
So, Alex, when you say "When you are using UmbracoHelper for retrieving data from Umbraco, it doesn't make request to db, it gets data from XML cache" does that mean retrieving data in other ways (e.g.,
Model.Content.GetPropertyValue("myField")
) does hit the db? Does that mean using UmbracoHelper is preferable most of the time?Regarding partial views and caching, the docs say this:
I took that to mean that partials are usually cached anyway, unless you're doing something weird which means you have to force caching. What does "You don't normally need to cache the output of partial views" really mean, and what are the circumstances under which it would be necessary to use
Html.CachedPartial
?Thanks for your time - really interesting thread.
Charles
Good questions, Charles.
No, using
Model.Content.GetPropertyValue("myField")
will NOT hit the DB.Neither will
@Umbraco.Field("myProperty")
or@Umbraco.TypedContent(1234)
. Nor will any queries suchMode.Content.Children()
orModel.Content.Descendants().Where(c => c.IsVisible() && c.DocumentTypeAlias == "MyDocTypeAlias")
Basically, anything that returns an instance of
IPublishedContent
doesn't hit the database. So all your standard querying you would normally use retrieve values from the cache (currently an XML Cache, but this may change in future). These are all "read-only" queries.You only really hit the DB in Umbraco if you use the ContentService methods which are read/write. But generally you only use these if you need to access unpublished content or wish to create new content programatically.
As for Partial caching...
I'm not sure I'd agree with the docs when they say:
Perhaps they mean that just retrieving content in Umbraco is fast and so doesn't really benefit too much from caching? But I'd still argue that if your content isn't changing much then it would benefit from partial caching. I usually cache all content on the home page and in things like the header and footer since this won't change often. The cache is automatically invalidated whenever any content is published, so you don't need to worry about "stale" content.
Just don't cache stuff that is truly dynamic, such as forms, and be careful to know when to cache globally and when to cache by page.
Excellent nuggets of info, Dan - many thanks. Today I've learned:
IPublishedContent
in VS using IntelliSense and know I'm getting cached content.So when you're in development using a cached partial and you make a change to it, how do you bust that cache?
The cache is automatically "bust" every time you publish any page in your site. So in the vast majority of cases you don't need to worry about it - it just "works".
Note that when Umbraco is in debug mode (ie.
debug
is set in compilation inweb.config
) then caching is turned off - it only kicks-in when debug is turned off. This makes dev easier as you don't need to worry about dealing with cached content during development.Right, got it. Didn't realise caching isn't a factor when debug mode.
Thanks Dan!
Hypothetically, if I put my Umbraco application behind a load balancer in 5 different containers, and lets say by default the XML Cache is stored in each container, how can I make sure that the XML Cache is synced and properly invalidated across the containers? Is there some configuration we can tamper with?
Basically, so long as you configure Umbraco correctly, then Umbraco takes care of syncing the XML cache and invalidating it etc.
See https://our.umbraco.org/documentation/getting-started/setup/server-setup/load-balancing/
is working on a reply...