Caching in TYPO3¶
TYPO3 uses multiple caching strategies to ensure fast content delivery. Depending on the content a page contains, TYPO3 chooses the best caching strategy for that use case.
For example, you might have a fully-cacheable page, a page that is at least partially
cacheable or a page that is completely dynamic. Dynamic elements in TYPO3 are also known
COA_INT objects - as these are the matching TypoScript objects used
to render non-cacheable content.
When visiting a TYPO3 web site, TYPO3 knows the following states:
first time hit, page has never been rendered ("cache miss")
consecutive hit, page has been rendered before ("cache hit")
In the first case, TYPO3 renders the complete page and writes cache entries as configured. In the second case, TYPO3 fetches those entries from the cache and delivers them to the user without re-triggering the rendering.
In that second case, either the page is fully cached and directly delivered from the cache, or the page has non-cacheable elements on it. If a page has non-cacheable elements, TYPO3 first fetches the cached part of the page and then renders all dynamic parts.
The cache contains placeholders for dynamic elements to tell TYPO3 where to render dynamic parts.
For developers: If you are developing a plugin think about your plugin's cache lifetime. Ideally, it can be fully cached, but if not, read the section about the caching framework to learn how to leverage TYPO3's caching mechanism to cache your plugin for however long you can - even 30 seconds might improve performance in some scenarios.
Caching Variants - or: What is a "cache hash"?¶
TYPO3 ideally delivers fully cached pages for maximum performance. However, in scenarios where the same page will deliver different content depending on URL parameters, TYPO3 needs a possibility to identify these "variants" and cache each of them differently. For example, if you have a news plugin and a detail page, the detail page is different for every news entry.
To identify the variant, TYPO3 combines a set of parameters and generates a hash value as identifier. These parameters include by default:
id: The current page ID
type: The current page type (
groupIds: The user groups of the logged in user (if no user is logged in: 0, -1 as default values)
MP: The mount point identifier
site: The current site and base URL
staticRouteArguments: Any route argument configured in the routing configuration and resolved in the current request
$_GETparameters influencing the rendered page
Imagine the following URL
https://example.org/news/?tx_example_news[id]=123 displaying the news with ID
If TYPO3 would cache that page with that parameter without any security mechanisms, it would open a potential
denial of service attack as an unlimited amount of cache entries could be generated by adding arbitrary parameters.
To avoid that, TYPO3 generates a so-called
cHash parameter, which is a hash that basically signs the valid parameters
for that request. So any parameter that validly influences the rendered page needs to be part of that
With Routing - "Speaking URLs" in TYPO3 you can configure TYPO3 not to display the
cHash in your URLs in most cases.
Routing adds an explicit mapping of incoming readable URL slugs to internal parameter values.
This both adds an additional layer for validating slugs as well as reduces the parameters to a limited (and predictable) set of values.
Various configuration options exist to configure the
cHash behavior via
in the file
Only the given parameters will be evaluated in the cHash calculation. Example: tx_news_pi1[uid]
Configure Parameters that require a cHash. If no cHash is given but one of the parameters are set, then TYPO3 triggers the configured cHash Error behavior
The given parameters will be ignored in the cHash calculation. Example: L,tx_search_pi1[query]
Configure Parameters only being relevant for the cHash if there's an associated value available. Set excludeAllEmptyParameters to true to skip all empty parameters.
If true, all parameters which are relevant for cHash are only considered if they are non-empty.
All properties can be configured with an array of values. Besides exact matches (equals) it is possible to apply partial matches at the beginning of a parameter (startsWith) or inline occurrences (contains).
URL parameter names are prefixed with the following indicators:
= (equals): exact match, default behavior if not given
^ (startsWith): matching the beginning of a parameter name
~ (contains): matching any inline occurrence in a parameter name
These indicators can be used for all previously existing sub-properties
Example (excerpt of
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = [ 'excludedParameters' => [ 'utm_source', 'utm_medium', ], 'excludedParametersIfEmpty' => [ '^tx_my_plugin[aspects]', 'tx_my_plugin[filter]', ], ];
For instance instead of having exclude items like
'excludedParameters' => [ 'tx_my[data][uid]', 'tx_my[data][category]', 'tx_my[data][order]', 'tx_my[data][origin]', ... ],
partial matches allow to simplify the configuration and consider all items having
tx_my[data][ to be more specific) as prefix like
'excludedParameters' => [ '^tx_my[data][', ... ],
Since TYPO3 CMS 4.3, the core contains a data caching framework which supports a wide variety of storage solutions and options for different caching needs. Each cache can be configured individually and can implement its own specific storage strategy.
The caching framework exists to help speeding up TYPO3 sites, especially heavily loaded ones. It is possible to move all caches to a dedicated cache server with specialized cache systems like the Redis key-value store (a so called NoSQL database).
Major parts of the original caching framework were originally backported from TYPO3 Flow.