---
title: "Automatic page cache clearing on Extbase record changes"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:extbase-caching-autoclearing@main"
source: "ExtensionArchitecture/Extbase/Caching/AutoClearing.rst"
rendered: "2026-09-24T12:36:55+00:00"
---

# Automatic page cache clearing on Extbase record changes {#extbase-caching-autoclearing}

When your plugin persists a change through a repository, the pages that display
that record are already in the page cache and would keep serving the old
content until their cache expired. Extbase prevents that: after a repository
write, it clears the cache of the pages affected by the change. This is the
default behavior, and the write-side counterpart to the read-side
[cache tags](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-cachetags@main) of the previous page.

**On this page**

-   [How an Extbase repository write clears the cache](https://docs.typo3.org/permalink/t3coreapi:how-an-extbase-repository-write-clears-the-cache@main)
-   [Which pages an Extbase record change clears](https://docs.typo3.org/permalink/t3coreapi:which-pages-an-extbase-record-change-clears@main)
-   [The page cache lifetime and where it comes from](https://docs.typo3.org/permalink/t3coreapi:the-page-cache-lifetime-and-where-it-comes-from@main)
-   [The enableAutomaticCacheClearing setting for Extbase](https://docs.typo3.org/permalink/t3coreapi:the-enableautomaticcacheclearing-setting-for-extbase@main)
-   [What automatic Extbase cache clearing does not cover](https://docs.typo3.org/permalink/t3coreapi:what-automatic-extbase-cache-clearing-does-not-cover@main)

## How an Extbase repository write clears the cache {#extbase-caching-autoclearing-flow}

Three repository operations trigger cache clearing: adding, updating and
removing a record. Each `INSERT`, `UPDATE` and `DELETE` that goes
through the Extbase persistence layer registers the affected record — its table
and UID —
for later clearing. At the **end of the request**, Extbase resolves the
registered records to page UIDs and flushes the page cache for those pages.

Two details are worth knowing:

-   Clearing happens **at the end of the request**, not the instant you call
    `add()` or `update()`. Several writes in one request are collected
    and their pages flushed together once.
-   Registration is driven by records, not relations. A write that only touches a
    relation (MM) table — with no record of its own —
    does not register a record for clearing.

## Which pages an Extbase record change clears {#extbase-caching-autoclearing-pages}

For each changed record, Extbase clears three kinds of page:

-   **Every page tagged with that record.** This is the primary mechanism and the
    reverse of [cache tags](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-cachetags@main). When a page renders
    a record, its cache entry is tagged with `<table>_<uid>`. When that
    record changes, Extbase flushes the `<table>_<uid>` tag, which
    invalidates every page carrying it. A conference shown on ten different list
    pages is therefore refreshed on all ten when it changes — without anyone
    configuring which pages those are. The storage page below is *not* how a list
    page gets cleared; the tag is.
-   **The record's storage page** — additionally, the page whose `pid` the
    record lives on is flushed (by its `pageId_<pid>` tag). This has no effect if
    the storagePid is a sysFolder, but for a content bearing page type it makes a difference.
    Consider the impact before deciding where a record stores as to not invalidate
    page caches for pages that might not even display that record.
-   **Any pages named in that page's** [TCEMAIN.clearCacheCmd](https://docs.typo3.org/m/typo3/reference-typoscript/main/en-us/PageTsconfig/TceMain.html#pagetcemain-clearcachecmd)
    **Page TSconfig.** An integrator can name further page UIDs to flush whenever
    *any* record on the storage page changes. Unlike the per-record tag above,
    this is a coarse, page-level rule the integrator maintains by hand — useful
    when a page depends on the storage folder as a whole rather than on one
    record.

## The page cache lifetime and where it comes from {#extbase-caching-autoclearing-lifetime}

Automatic clearing flushes a page *early*, when its records change. Absent any
change, a cached page lives until its lifetime expires. That lifetime is not a
single fixed number — it is resolved from several sources, each overriding or
narrowing the previous:

1.  **The page's Cache timeout field** (**Page > Behavior > Cache
    timeout**). If set to a non-zero value, it wins.
1.  **TypoScript** `config.cache_period`. Used when the page field is
    not set.
1.  **A framework fallback** when neither of the above applies. In the calculator
    that handles record and page lifetimes this fallback is one year; a separate
    24-hour fallback applies to the content-object rendering path. Treat these as
    innermost fallbacks, not as "the" default.
1.  **Narrowed by record visibility.** The lifetime is then shortened to the next
    `starttime` or `endtime` of the records on the page, so a page
    expires no later than the moment its content becomes visible or hidden.
1.  **Overridden by an event.** Finally, a listener on
    [ModifyCacheLifetimeForPageEvent](https://docs.typo3.org/permalink/t3coreapi:modifycachelifetimeforpageevent@main)
    receives the resolved value and may replace it entirely.

Because of this chain, do not rely on a hard-coded number for "how long a page is
cached". If you need the real, effective value for a given page, verify it rather
than infer it:

-   **Inspect the cache entry.** With the default database cache backend, the
    `cache_pages` table stores an `expires` timestamp for each cached
    page. The remaining lifetime is `expires` minus the current time.
-   **Observe the resolved value.** A listener on
    [ModifyCacheLifetimeForPageEvent](https://docs.typo3.org/permalink/t3coreapi:modifycachelifetimeforpageevent@main) is
    handed the fully resolved lifetime for the page; logging it there reports
    exactly what the system computed, after every source above has been applied.

## The `enableAutomaticCacheClearing` setting for Extbase {#extbase-caching-autoclearing-setting}

Automatic clearing is controlled by
`config.tx_extbase.persistence.enableAutomaticCacheClearing`, which is
**enabled by default**:

**EXT:my_extension/Configuration/Sets/MyExtension/setup.typoscript**

```typoscript
config.tx_extbase {
  persistence {
    # On by default. Set to 0 to stop repository writes from clearing
    # the page cache automatically.
    enableAutomaticCacheClearing = 1
  }
}

```

The setting gates the *flush*, not the *registration*: repository writes always
register their changed records, and the setting decides whether those registered
pages are cleared at the end of the request.

This is a **global** TypoScript setting in `config.tx_extbase`. It
applies to every repository write on the site for as long as it is set, and there
is no supported way to toggle it temporarily from PHP for a single operation —
unlike `\TYPO3\CMS\Core\DataHandling\DataHandler`, whose runtime behavior
can be adjusted per instance. Setting it to `0` therefore means every
repository write across the site stops refreshing the frontend, and clearing
caches becomes your own responsibility through the
[cache-clearing helper](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-cachetags-clearing@main). Leave it at its
default unless a deliberate, site-wide cache strategy replaces it.

## What automatic Extbase cache clearing does not cover {#extbase-caching-autoclearing-limits}

This mechanism is Extbase's own, and it only reacts to writes made **through an
Extbase repository**. It does not cover:

-   **Raw database writes** — records changed with a
    DBAL
    `\TYPO3\CMS\Core\Database\Query\QueryBuilder` query bypass the Extbase
    persistence layer, register nothing, and clear no cache. After such a write
    you must clear the affected pages yourself with the
    [cache-clearing helper](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-cachetags-clearing@main).
-   **Relation-only changes** — as noted above, a write that only touches an
    MM table registers no record.
-   **Caches outside the pages group** — automatic clearing flushes by tag
    within the `pages` cache group, calling `flushByTags()` on **every**
    cache registered in that group, not only the page cache itself. A custom cache
    is reached by this **if you register it into the** `pages` **group and tag
    its entries** with the same `<table>_<uid>` value — which is exactly what
    you want for a cache that stores rendered output, so it is invalidated
    together with the page cache. A custom cache left in the default `all`
    group is *not* in the pages group and is not touched, so you must invalidate
    it yourself. The two-level list cache from
    [the optimisation section](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-noncacheable-optimise@main) uses
    the pages group for precisely this reason.

`\TYPO3\CMS\Core\DataHandling\DataHandler` is a different case: it is not
covered by *this* mechanism, but it clears caches on its own. A DataHandler write
registers the changed record for page-cache clearing through its own routine and
honors the same [TCEMAIN.clearCacheCmd](https://docs.typo3.org/m/typo3/reference-typoscript/main/en-us/PageTsconfig/TceMain.html#pagetcemain-clearcachecmd) Page TSconfig — so records
written through DataHandler do refresh the frontend, just not via the Extbase path
described here.

With this, you have the full caching picture for an Extbase plugin: cached by
default, non-cacheable only when you must, invalidated precisely with cache tags,
and refreshed automatically when records change.

> [!NOTE]
> **See also**
>
> -   [Caching for Extbase plugins](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-overview@main) — the chapter overview.
> -   [Cache tags for Extbase plugins](https://docs.typo3.org/permalink/t3coreapi:extbase-caching-cachetags@main) — the read-side counterpart: tagging pages so they can be invalidated.
