Enable and Configure TYPO3 Frontend Output Caching with TypoScript
Learn how to turn on TYPO3’s frontend output cache with TypoScript, set lifetimes and tags, switch backends, and verify caching via response headers.
23 Aug 2025, 22:30 UTC

Quick answer: turn on frontend caching in TypoScript
To have TYPO3 serve cached HTML for a page type, add the following lines to the TypoScript template that controls that page (usually in the Setup field of the root template or a page-specific template):
config.cache = 1
config.cache_lifetime = 3600
config.cache_tag = tx_myext_pi1
This tells TYPO3 to:
- Enable the FrontendOutput cache (
config.cache = 1). - Store each cached page for one hour (
config.cache_lifetime = 3600seconds). - Tag the cache with
tx_myext_pi1so that any change to records handled by the extensionmyextcan purge the relevant pages.
How the mechanism works
TYPO3’s caching framework separates the frontend (what the browser sees) from various backends where cached data is stored. When config.cache is set, TYPO3 checks the frontend cache before rendering the page:
- On the first request, TYPO3 builds the page normally, stores the generated HTML in the frontend cache, and tags it with the value of
config.cache_tag. - On subsequent requests within the lifetime, TYPO3 returns the cached HTML directly, skipping most TypoScript processing and database queries.
- If any part of the TypoScript sets
no_cache = 1(e.g., a plugin that depends on a session or a user‑specific condition), the cache is bypassed for that request. - When a record that matches a cache tag is updated, TYPO3 can flush all cache entries bearing that tag, ensuring the next request sees fresh content.
- In the plugin’s controller, assign a tag that includes the extension key and the post UID (or a generic tag for the list):
- In the TypoScript template for the page that holds the plugin, enable caching and set the tag:
- Make sure the extension’s persistence layer triggers a tag flush on post changes. Using a DataHandler hook is the simplest:
- Register the hook in
ext_localconf.php: - Enable the frontend cache as shown above.
- Open the page in a browser or with
curl -I https://example.com/pageand look for the header: - Change a record that should affect the output, flush the corresponding tag (via backend or CLI), and reload. The sequence
MISS → HITconfirms invalidation and regeneration.
Worked example: caching a blog extension
Assume you have an extension blog with a plugin that lists posts. You want the list page to be cached, but you also want the cache cleared when a new post is added or an existing post is edited.
// In BlogController::listAction()
$this->view->assign('tags', ['tx_blog_pi1']);
config.cache = 1
config.cache_lifetime = 7200
config.cache_tag = tx_blog_pi1
// EXT:blog/Classes/Hooks/DataHandlerHook.php
class DataHandlerHook implements \TYPO3\CMS\Core\DataHandling\DataHandlerInterface {
public function processDatamap_postProcessFieldArray($status, $table, $id, array &$fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler $parentObject): void {
if ($table === 'tx_blog_domain_model_post') {
$cache = $parentObject->getCacheManager()->getCache('frontend');
$cache->tag->flushTag('tx_blog_pi1');
}
}
}
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamap_class'][] =
'VENDOR\Blog\Hooks\DataHandlerHook::class';
Now, whenever a post is saved, the frontend cache for any page tagged tx_blog_pi1 is cleared, and the next visitor receives a freshly rendered list.
Limits and common mistakes
1. Cache lifetime too long
Setting config.cache_lifetime to a very large value (e.g., 86400 seconds for a day) can serve stale content if editors update records more frequently. The cache will not be refreshed until the lifetime expires or a tag flush occurs.
Check: After changing a record, wait a few seconds and reload the page. If you still see the old content, the lifetime is likely the cause. Reduce the value or rely on tag flushing.
2. Overriding no_cache
Any TypoScript condition, plugin, or extension that sets no_cache = 1 disables the frontend cache for that request, regardless of config.cache. Common culprits are plugins that use fe_user sessions or custom TypoScript like:
[globalVar = TSFE:fe_user|user|uid > 0]
no_cache = 1
[global]
Check: Log in as a frontend user and request the page. If the response header shows X-TYPO3-Cache: MISS even though config.cache = 1, look for a no_cache setting in the TypoScript object browser.
3. Backend performance bottlenecks
The default Database backend stores cache rows in the cache_* tables. On high‑traffic sites this can create lock contention and slow down both reads and writes.
Solution: Switch to the File or Redis backend. Add the following to AdditionalConfiguration.php (requires file‑system write permission for the web user):
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['frontend']['backend'] =
\TYPO3\CMS\Core\Cache\Backend\FileBackend::class;
// Optional: define cache directory
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['frontend']['options'] = [
'cacheDirectory' => 'typo3temp/var/cache/',
];
After saving, clear all caches (typo3cms cache:flush or via the Admin Tools) and reload a page. You should see new files appear under typo3temp/var/cache/ and, under load, improved response times.
Risk: If the web server cannot write to the configured directory, TYPO3 will fall back to the Database backend silently, causing unexpected performance issues. Verify permissions (chmod -R 775 typo3temp/var/cache and ownership matching the web‑server user).
4. Forgetting to flush tags
If you rely on tag‑based invalidation but never call flushTag() (or forget to configure config.cache_tag), the cache will never be cleared, leading to outdated content.
Practical verification: After updating a record, manually flush the tag via the CLI:
typo3cms cache:flush --tag tx_blog_pi1Then reload the page and confirm the header changes fromHITtoMISSand back toHITafter the new cache is stored.How to verify that caching is working
X-TYPO3-Cache: HITThe first request will show
MISS(cache being stored). Subsequent requests within the lifetime should showHIT.
Rollback considerations
Enabling
config.cachedoes not alter database schema or permanent files; it only changes runtime behavior. If you discover that caching causes issues, simply setconfig.cache = 0or remove the lines from TypoScript and clear the cache. No data migration is needed.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.