DEV Community

Magevanta
Magevanta

Posted on • Originally published at magevanta.com

MySQL Query Cache vs Magento Cache: What's the Difference and When to Use Each

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

  1. A SELECT query arrives at MySQL.
  2. MySQL hashes the query string and checks the query cache.
  3. If there's a hit, the result is returned immediately.
  4. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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',
            ],
        ],
    ],
],
Enter fullscreen mode Exit fullscreen mode

For high-traffic stores, put Varnish in front:

bin/magento config:set --scope=default system/full_page_cache/caching_application 2
Enter fullscreen mode Exit fullscreen mode

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)