Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add native tag-based caching to Plone #4114

Open
pgrunewald opened this issue Feb 14, 2025 · 0 comments
Open

Add native tag-based caching to Plone #4114

pgrunewald opened this issue Feb 14, 2025 · 0 comments

Comments

@pgrunewald
Copy link

pgrunewald commented Feb 14, 2025

PLIP (Plone Improvement Proposal)

Responsible Persons

Proposer: @pgrunewald

Seconder:

Abstract

Plone lacks support for tag-based caching and invalidation. Enabling this by default would allow much longer caching times while still serving always up-to-date content. This also significantly increases the hit rate, because less content expires unnecessarily.

Motivation

Thijs Feryn, a specialist for caching and tech evangelist at Varnish Software, spoke at the Plone Conference in Brasilia (talk #1 & talk #2) and advertised cache tags for having a much finer cache-control and invalidation. The name for this technique is called xkey/ykey in Varnish. Currently, almost every single page served by Plone is composed of multiple content objects. Whenever one of these objects is invalidated, the page using those objects should be invalidated as well.

The current solution for this problem is backed by plone.app.caching and is archieved by implementing an IPurgePath-adapter which gathers all references of the to-be-purged object (like via the isReferencing relationship). Then, all possible URLs with their default view names of these have to be generated and sent as multiple PURGE request to the cache server.

While this approach might work, it has downsides: It is cumbersome, error-prone and wasteful due to the number of sent requests. A better way is to to explicit state in the response, that for composing this page the objects X and Y are involved. This can be achieved by including the UUIDs of the objects as cache tags in the HTTP response header. When purging an object, only one PURGE request is sent and all cache entries containing this cache tag in their HTTP response header are purged as well.

This concept described is known as Cache Keys or Surrogate Keys and utilized by several products:

  • CMSes: Drupal 8/9/10, Typo3, Magento 2 (shop software)
  • CDNs/Caching servers: Fastly, Cloudflare enterprise, Varnish

See this blog post for reference.

With this finer cache control, it is also possible to target specific types of pages (e.g. all news pages, etc.)

Assumptions

Caching times are currently considerable low, but could be greatly increased improving the hit rate and overall the received responsiveness.

Proposal & Implementation

There is already an add-on called collective.purgebyid that introduces an extra HTTP-header can contains all the cache tags of involved objects when a page is published. For further details see the section How does it work? How to extend it?

This add-on is already high-quality and should be part of the Plone core. It should be used in places that render different objects, such as when an image scale is displayed or a listing of news items in a collection is generated. This can be done in a adapter-like fashion or directly at the moment an object is being used.

We at TUD are already using this technology, which has allowed us to extend caching times significantly. That being said, we only generate pages in the Classic UI way via page templates. The plone.restapi must be improved by adding the special HTTP header with all the cache tags of the delivered objects. This is in my opinion very feasable. However, as the author of this PLIP, I am currently unsure how this can be implemented in Volto's server-side rendering (SSR). That said, Volto should still benefit from the longer cached Plone API calls.

Deliverables

  • Integrate collective.purgebyid into Plone core (moving from collective to plone namespace, probably renaming etc.).
  • Add support in plone.restapi
  • Add support for add-ons that are using template rendering for its content (e.g. plone.app.contenttypes)
  • Add support for Volto SSR (?)
  • Update developer documentation on how to use cache tags and set up the infrastructure (see Risks)

Risks

The HTTP response header will obviously increase. This is not a problem for Plone itself, but might be a problem for the server infrastructure in front of Plone:

For Apache, nginx and Varnish the maximum HTTP response header size varies from 4K to 8K and might be increased individually, when the header bloats up due to the number of objects on the page.

Since this may break sites, the delivery of the new header will be disabled by default and can be enabled when needed. A checkbox for this should be added in the Caching control panel.

Participants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant