Cache Types

Magento's cache is split into about fifteen named types; cache:status reports them and cache:clean targets one.

Syntaxbin/magento cache:clean [<type> ...]

Magento does not have one cache. It has roughly fifteen separate cache types, each a named slice holding one kind of derived data. config holds the merged XML configuration. layout holds merged page structure. block_html holds HTML fragments produced by individual blocks. full_page holds whole rendered pages. Others hold table definitions (db_ddl), attribute metadata (eav), collection results (collections), translations (translate), web API configuration (config_webservice) and GraphQL resolver output (graphql_query_resolver_result, from the Magento_GraphQlResolverCache module). A target_rule type appears only on Adobe Commerce, which ships the related-product rule engine.

Seeing the state

bin/magento cache:status prints each type with 1 for enabled and 0 for disabled. A type can also be invalidated: still enabled, but holding data Magento knows is stale. The admin shows that as INVALIDATED. bin/magento cache:enable config and cache:disable config change the first state; cache:clean config clears the second.

Clean is not flush

cache:clean removes Magento's own tagged entries for the types you name. cache:flush empties the entire storage behind them. The long and short forms of a command are the same thing: bin/magento cache:clean config and bin/magento c:c config run identical code, because the CLI accepts any unambiguous abbreviation.

What trips people up

Flushing everything after every edit hides which type was stale, so you never learn the mapping: a changed di.xml needs config, a changed template needs block_html and full_page. Name the type.

Example

Example · php
<?php
// app/code/Vendor/CacheTools/Console/Command/InvalidateCommand.php
declare(strict_types=1);

namespace Vendor\CacheTools\Console\Command;

use Magento\Framework\App\Cache\TypeListInterface;
use Magento\Framework\Console\Cli;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class InvalidateCommand extends Command
{
    public function __construct(
        private readonly TypeListInterface $typeList,
        ?string $name = null
    ) {
        parent::__construct($name);
    }

    protected function configure(): void
    {
        $this->setName('vendor:cache:invalidate');
        $this->setDescription('Marks the named cache types as invalidated');
        $this->addArgument(
            'types',
            InputArgument::IS_ARRAY | InputArgument::REQUIRED,
            'Cache type codes, for example config layout'
        );
        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $types = $input->getArgument('types');
        $this->typeList->invalidate($types);
        $output->writeln('Invalidated: ' . implode(', ', $types));

        return Cli::RETURN_SUCCESS;
    }
}

// $ bin/magento vendor:cache:invalidate config layout
// Invalidated: config, layout

When to use it

  • Working out which cache type to clear after editing a di.xml, a template or a config value.
  • Checking whether a storefront problem is a stale cache or a real code fault, without flushing production.
  • Writing a deployment step that invalidates only the types a release actually affects.

More examples

Registering the command

A console command class is invisible until it is added to the commands array of Magento\Framework\Console\CommandList. Run bin/magento setup:upgrade then bin/magento cache:clean config, and the command appears in bin/magento list. If it does not, the config cache is still holding the old command list.

Example · xml
<!-- app/code/Vendor/CacheTools/etc/di.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="vendorCacheInvalidate" xsi:type="object">
                    Vendor\CacheTools\Console\Command\InvalidateCommand
                </item>
            </argument>
        </arguments>
    </type>
</config>

Reading the state before you clear anything

cache:status is the first command to run when a change does not show up. Reach for this before cache:flush: the two types above cover almost every "my template edit did nothing" report, and clearing them alone leaves the config and collection caches warm.

Example · bash
$ bin/magento cache:status
Current status:
                        config: 1
                        layout: 1
                    block_html: 1
                   collections: 1
                     full_page: 1
                     translate: 1

$ bin/magento cache:clean layout block_html
Cleaned cache types:
layout
block_html

Listing only what is stale

TypeListInterface::getInvalidated() is what the admin's INVALIDATED badge reads. The constructor here is written longhand: a declared property plus an assignment. The promoted form used in the main example, private readonly TypeListInterface $typeList, is shorthand for exactly these two lines and compiles to the same class.

Example · php
// Vendor\CacheTools\Model\StaleReport (constructor body shown longhand)
private TypeListInterface $typeList;

public function __construct(TypeListInterface $typeList)
{
    $this->typeList = $typeList;
}

public function getStaleCodes(): array
{
    // getInvalidated() returns the types Magento has marked stale,
    // keyed by type code, with label and description for each.
    return array_keys($this->typeList->getInvalidated());
}

Discussion

  • Be the first to comment on this lesson.