Skip to content

Caching and Cache Times

jonhadley edited this page Aug 7, 2023 · 9 revisions

Caching overview

Cache being specified allows the cache headers to be set (this is usually viewable in the network tab of developer tools) e.g.

Cache-Control:public,max-age=1800

Caching helps out website in a number of ways

  • Increases performance/load times for users
  • Reduces load on our infrastructure
  • Reduces hits to Contentful

Caching can potentially happening in a number of places, and all these different caching options work together to reduce the load on our application and improve performance for users.

Problems with caching

The very purpose of cache is to prevent hits on the application, the generation of new pages. When pages are being updated regularly, updates are urgent or page contain an element of "timeliness" this can result odd effects. For example a news article may be slow to update or their humanised last updated time may appear stuck.

The above is expected behaviour but can be a bit confusing for less aware users. To mitigate this we need to carefully consider/document our cache times especially in areas of the site with high frequency of updates.

Cache busting

As per the below it's possible to bust/invalidate caches either through browser controls or pipeline that clear CDN caches. It's less easy/obvious how we would deal with in app caching issues. For example, how is the footer cache cleared?

Types of caching

Browser

Browser cache will keep a copy of visited pages, it will/should also cache assets required to render the page such as images, CSS and javascript. Pages rendered from browser cache have no impact on our infrastructure.

If required browser cache can usually be cleared by pressing ctrl+F5, failing that clearing browsing data will help.

Cloudfront/CDN (Content Delivery Network)

CDNs are distributed cache servers, usually they are geographically local to users (so content could be cached for UK users but not for those in the US). As with browser cache the CDN will obey the cache header. The benefit of using a CDN is that multiple users can be served from the same cache.

CDN Cache can be manually invalidated using the relevant "Lambda" pipeline in CI.

The cloud front cache does not sit in front of the "origin" URL of the website.

Note

With any pages that are providing a personalised service, we need to careful thaesepages are not cached in CDNs.

CDNs can be configured to cache based on other values in a request, such as cookies, business ID or other header values (for example the presence of the "alerts" cookie will result in a separate cache) - this needs to be configured separately in the CDN.

Between 40-50% of traffic to Stockport.gov.uk is served from the Cloudfront

In Application

For performance reasons or to prevent the loading/requesting of the same data repeatedly, developers my choose to cache specific parts of pages or collections of data between requests.

For example, rendering the footer of the website causes requests to be made to contentful, so that the footer and social media links can be added. These change very rarely and as such could be cached for a very long time. This is done by caching the footer component individually, so that even if a user is requesting and un-cached page, the shared footer portion is likely still being retrieved from a longer running in application cache.

For developers

Cache times are commonly applied using ResponseCacheHeader

[ResponseCache(Location = ResponseCacheLocation.Any, Duration = Cache.Medium)]

Note the use of the Cache constant StockportWebapp.Constants.Cache. The common values should be used wherever possible when specifying a cache length value.

Where caching is applied

  1. In the controller or above the action: [ResponseCache(Location = ResponseCacheLocation.Any, Duration = Cache.Medium)]~

  2. In views (for smaller where there is far less content turnover) <distributed-cache name=footer [email protected](ApplicationConfiguration.GetFooterCache(BusinessId.ToString())) enabled=true> @await Component.InvokeAsync("Footer") </distributed-cache>

  3. In application code - It's also possible to cache/persist small chunks of data on controller or service level code (akthough there are not any current examples of this!)

Cache Times

Cache Times are split into the following values

Name Time (Seconds) Time(Minutes)
Short 900 15
Medium 1800 30
Long 3600 120
Page/Component/Data Cache Scheme Headers/In Application
Homepage Medium Headers
Footer Custom Config - 1440 minutes/24 Hours In Application