Caching is one of the most effective levers you have for speeding up a Magento 2 store. But "caching" is not a single thing — it's a stack of overlapping layers, each operating at a different level of your infrastructure. Two layers that often cause confusion are MySQL's query cache and Magento's built-in cache. They sound similar, they both exist to serve data faster, but they work in completely different ways and serve completely different purposes.
This post breaks down exactly what each one does, where they overlap, where they don't, and how to configure them properly for a production Magento 2 environment.
What Is MySQL Query Cache?
MySQL's query cache is a server-level feature that stores the result set of a SELECT query alongside the raw SQL string. If the exact same query comes in again — character for character — MySQL returns the cached result without re-executing the query against the tables.
It sounds like a win, but the reality is more nuanced.
How it works
- A
SELECTquery arrives at MySQL. - MySQL hashes the query string and checks the query cache.
- If there's a hit, the result is returned immediately.
- If there's a miss, the query executes, and the result is stored in the cache.
The key problem: any write to a table invalidates all cached queries that reference that table. In a busy Magento store, tables like sales_order, catalog_product_entity, quote, and cataloginventory_stock_item are written to constantly. Every new order, every cart update, every stock decrement — all of these flush cached query results.
MySQL 8.0 removed it entirely
MySQL 8.0 deprecated and removed the query cache. The MySQL team found that in high-concurrency environments, the query cache was actually a bottleneck due to the global mutex needed to manage cache invalidation. For Magento stores running MySQL 8.0 (which is now the standard), the query cache is simply not available.
If you're still on MySQL 5.7, the query cache is present but disabled by default (query_cache_type = 0). For most Magento workloads, leaving it disabled is the right call.
What Is Magento Cache?
Magento's cache operates at the application layer, not the database layer. Rather than caching SQL results, it caches serialized PHP objects, rendered HTML blocks, configuration arrays, and more. It uses a cache backend (File, Redis, Varnish) to store and retrieve these objects.
Magento ships with several distinct cache types, each serving a specific purpose:
| Cache Type | What It Stores |
|---|---|
config |
Merged XML configuration |
layout |
Page layout handles and block structure |
block_html |
Rendered HTML of individual blocks |
collections |
EAV collection results |
reflection |
PHP class reflection data |
db_ddl |
Database table schema metadata |
compiled_config |
DI compiled configuration |
full_page |
Complete rendered page HTML (FPC) |
translate |
Translation strings |
eav |
EAV attribute metadata |
Each of these can be enabled or disabled independently:
bin/magento cache:status
bin/magento cache:enable full_page
bin/magento cache:disable block_html
The Full Page Cache
The most impactful of these is full_page — Magento's Full Page Cache (FPC). When a CMS page, category page, or product page is first rendered, the entire HTML response is stored. Subsequent requests for the same page serve the cached HTML without touching PHP or MySQL at all.
FPC can be served by:
- Magento's built-in FPC (file-based or Redis-based, ~50–200ms response)
- Varnish (reverse proxy, ~5–20ms response — the production-grade choice)
How They Interact
Here's the key insight: these two caching layers are almost entirely independent.
When Magento serves a cached full page, MySQL is not involved at all. When Magento's block cache is warm, it may skip several database queries entirely. Conversely, MySQL query cache (on 5.7) only kicks in when Magento actually executes a SELECT — which it tries hard to avoid by using its own cache first.
The interaction diagram looks like this:
Request
└─► Varnish FPC hit? → Serve HTML (MySQL never touched)
└─► Magento FPC hit? → Serve HTML (MySQL never touched)
└─► Block cache / config cache hit? → Partial PHP execution
└─► MySQL query
└─► MySQL query cache hit? (5.7 only) → Return result
└─► Execute query against tables
In practice, a warm Magento cache means MySQL sees dramatically fewer queries. The MySQL query cache, when it was still available, only helped at the very bottom of this chain — for queries that escaped all of Magento's own caching layers.
Configuration Recommendations
MySQL (5.7)
If you're still on MySQL 5.7, keep the query cache disabled:
# /etc/mysql/mysql.conf.d/mysqld.cnf
query_cache_type = 0
query_cache_size = 0
The write-invalidation behavior combined with Magento's write-heavy workload makes it a net negative in most cases. Spend the memory on innodb_buffer_pool_size instead — that's where your MySQL performance gains are.
# For a server with 16GB RAM dedicated to MySQL
innodb_buffer_pool_size = 10G
innodb_buffer_pool_instances = 8
MySQL (8.0)
Nothing to configure — the query cache doesn't exist. Focus on InnoDB tuning.
Magento Cache Backend
For any production store, use Redis as the cache backend. File-based caching is fine for development but falls apart under load due to filesystem contention.
bin/magento setup:config:set \
--cache-backend=redis \
--cache-backend-redis-server=127.0.0.1 \
--cache-backend-redis-port=6379 \
--cache-backend-redis-db=0
For the session cache, use a separate Redis instance or at least a separate database index:
bin/magento setup:config:set \
--session-save=redis \
--session-save-redis-host=127.0.0.1 \
--session-save-redis-port=6379 \
--session-save-redis-db=1
Full Page Cache
In app/etc/env.php, confirm FPC is set to Redis (or Varnish if applicable):
'cache' => [
'frontend' => [
'full_page' => [
'backend' => 'Cm_Cache_Backend_Redis',
'backend_options' => [
'server' => '127.0.0.1',
'port' => '6379',
'database' => '2',
],
],
],
],
For high-traffic stores, put Varnish in front:
bin/magento config:set --scope=default system/full_page_cache/caching_application 2
Quick Reference: Which Cache Layer to Focus On
| Situation | Recommended Action |
|---|---|
| Pages loading slowly, TTFB > 500ms | Enable Varnish or Magento FPC |
| MySQL CPU spiking under load | Check InnoDB buffer pool, not query cache |
| Slow admin panel after deploy | Run bin/magento cache:flush
|
| Query cache enabled on MySQL 5.7 | Disable it — likely a net negative |
| Dev environment with slow page loads | Enable all Magento cache types |
| Session-related slowness | Move sessions to Redis |
Summary
MySQL query cache and Magento cache are two different tools solving different problems at different layers of the stack. For modern Magento 2 on MySQL 8.0, MySQL query cache is not a factor — it no longer exists. Your caching focus should be entirely on Magento's application cache, with Redis as the backend and Varnish (or Magento FPC) handling full-page responses.
The real performance wins in Magento come from eliminating PHP and database execution altogether — not from making individual SQL queries slightly faster. Invest in the upper layers of the cache stack first, then tune the database buffer pool, and don't waste time chasing a query cache that either doesn't exist or actively hurts you.
Top comments (0)