bin/magento cache:clean removes Magento's own entries for the cache types you pass (or every cache type, if you pass none), and leaves anything else in that storage alone. bin/magento cache:flush wipes the entire cache storage (every key in that Redis database or cache folder), including data other apps put there. Use clean day to day, and flush when clean doesn't fix it.
A University student asked this on Campus, a premium community for Magento developers available to University students, and it's the most common cache question I get:
…which reminds me of this post on X from 2022! 😁
That post happened to get a lot of engagement with a lot of great replies. I decided to write up a more formal explanation of what’s going on with Magento’s cache, and summarize how it works.
This was the exact reply posted back to Bhargav’s question, but I wanted to cross-post it here as it also makes a great blog post.
If you are interested in getting detailed answers to your Magento questions just like this, consider enrolling in the University.
About cache types, frontends & backends
Before starting, it's important to know the difference between cache types, cache frontends and cache backends.
Every cache type (config, layout, full_page and so on) is assigned to a cache frontend, and each frontend has
its own backend, which is the storage the entries actually land in. One frontend can serve many cache types.
Out of the box, Magento stores its cache in files: the default frontend writes to var/cache and the page_cache
frontend writes to var/page_cache. Most real setups switch that to Redis (or Valkey) with
bin/magento setup:config:set --cache-backend=redis, and that's what docker-magento
configures for you. Those frontends are then defined in the app/etc/env.php file:
...
'cache' => [
'frontend' => [
'default' => [
'id_prefix' => '69d_',
'backend' => 'Magento\Framework\Cache\Backend\Redis',
'backend_options' => [
'server' => 'redis',
'database' => '0',
'port' => '6379',
'password' => '',
'compress_data' => '1',
'compression_lib' => ''
]
],
'page_cache' => [
'id_prefix' => '69d_',
'backend' => 'Magento\Framework\Cache\Backend\Redis',
'backend_options' => [
'server' => 'redis',
'database' => '1',
'port' => '6379',
'password' => '',
'compress_data' => '0',
'compression_lib' => ''
]
]
],
'allow_parallel_generation' => false
],
...In a docker-magento (or typical Redis) install there are two cache frontends: default and page_cache. Both use the Redis backend, but note that one is assigned to database 0 and the other is assigned to database 1. So every cache entry lands in one of these two Redis databases.
Magento is very flexible & extensible, so you could always define additional cache frontends if your needs warrant them.
Since there are only two frontends, all cache types fall into one of them. To put it simply, the full_page cache
type is stored in the page_cache frontend (Redis database 1), and all other cache types are stored in the
default frontend (Redis database 0). If you run Varnish (system/full_page_cache/caching_application set to 2),
full page cache entries live in Varnish instead, and Magento sends it purge requests.
When to use each
Your everyday command is cache:clean. Pass types to scope it, or none to clean them all:
bin/magento cache:clean
bin/magento cache:clean layout full_pagecache:clean removes only the entries tagged with each cache type's tag, so it never touches anything else living in
the same storage. For development environments, you might want to configure automatic cache clearing in Magento to streamline your workflow and avoid manual cache operations during active development.
If clean doesn't fix it, and you need the cache storage wiped completely, use the cache:flush command:
bin/magento cache:flushThis wipes the whole storage behind every cache frontend (on Redis, that's a FLUSHDB on each database), including
any non-Magento keys that happen to live in the same database. That's why flush is the one to be careful with on a
shared Redis.
Why cache:flush with arguments is misleading
So would you ever want to do this?
bin/magento cache:flush layout full_pageThe answer is a resounding: NO! 😄
cache:flush doesn't flush cache types at all. It looks up the frontend behind each type you pass and wipes that
entire storage. layout lives in the default frontend, so the command above wipes every type in Redis database 0,
plus all of database 1 for full_page. Passing types only makes it look scoped. This is actually bad core
functionality and should be deprecated.
Magento should add a command like this instead:
bin/magento cache:purge [CACHE_BACKEND]So rather than specifying specific cache types to clear with cache:purge, you would specify the cache backend(s)
you'd like to clear instead.
I'd normally consider changing the cache:flush command to do this, but unfortunately that command is very much
ingrained in everyone's brain since the dawn of Magento time, so this would probably not be a popular update (unless it
can be made into a major version update).
Introducing a new command to do this with proper functionality makes more sense to me, and this would also help avoid the ambiguity that exists between clean and flush.
Which admin button does what?
There's also ambiguity between the cache buttons in the admin:
Since the "Flush Cache Storage" button prompts you with a modal that warns you the cache storage may contain additional data if flushed:
...this is the equivalent of the cache:flush command.
The "Flush Magento Cache" button should probably be renamed "Clean Magento Cache", because that is much more
semantically correct with its alignment to the cache:clean command. Adobe's own
cache docs spell
it out: "Flush Cache Storage is equivalent to bin/magento cache:flush. Flush Magento Cache is equivalent to bin/magento
cache:clean."
Some additional thought probably needs to be put into both of these button actions, as they are extremely ambiguous and lead to the confusion that everyone has with clearing the related caches.
If there's a cache behavior that still trips you up after all this, let me know what it is. Odds are someone else is stuck on the same thing.



