Query Cache
Older MySQL tutorials sometimes recommend enabling the query cache. For WordPress, it is usually a net negative: it can introduce contention under concurrency and provides limited benefit for an application that constantly writes to shared tables (options, sessions, orders, carts).
Do not enable the MySQL query cache for WordPress.
- MySQL removed query cache in 8.0.
- On older MySQL or on MariaDB, ensure any query cache directives are disabled/removed.
The Structural Failure of Query Cache
The theoretical concept of trapping database query results locally to avoid redundant fetching logically aligns with the WordPress caching paradigm. However, the exact mechanical execution of the MySQL internal cache completely destroys concurrent applications.
The Invalidation Death Loop
The MySQL Query Cache operates blindly utilizing exact macroscopic table-level validation rules.
- The cache logs the exact result of
SELECT * FROM wp_options WHERE option_name = 'siteurl'. - A random plugin cleanly fires an
UPDATEcommand altering a completely unrelated row deeply inside the exact samewp_optionstable. - Because the
wp_optionstable formally received a write command, the legacy Query Cache systematically dumps the entirety of every single cached query strictly tied to that table instantly, regardless of explicit mapping. - The database subsequently burns massive CPU cycles attempting to rebuild the destroyed caching matrix, only for another background plugin to instantly trigger the identical table-invalidation purge.
The Global Locking Bottleneck
To securely maintain absolute data integrity during these massive invalidation purges, the database engine enforces a hard global mutex lock. During this lock, the database strictly entirely refuses to accept any incoming SELECT statements globally, forcing all active PHP FPM workers to hang completely simultaneously until the purge formally finalizes.
The Disablement Procedure
You must cleanly map the configuration directly into your master configuration file to definitively ensure the cache engine shuts down natively.
1. Identify the Current State
# Query the active runtime variables securely
mysql -e "SHOW VARIABLES LIKE 'query_cache%';"
If query_cache_size returns any integer greater than zero safely, or query_cache_type registers as ON, you are actively shedding CPU resources managing a fragmented cache.
2. Force the Disablement Directive
Inject the explicit overrides into the configuration safely:
[mysqld]
# Ensure the logic strictly maps to zero mathematically
query_cache_type = 0
query_cache_size = 0
query_cache_limit = 0
3. Cycle the Execution Engine
sudo systemctl restart mysql
The Mandatory Alternative (Object Caching)
If you disable the database query cache, the replacement is not another database-level cache. Instead, use the right caching layers for WordPress:
- Page cache + CDN cache for public pages
- InnoDB buffer pool for hot data/index pages
- Object caching (Redis) for repeated dynamic lookups (especially logged-in/admin/checkout flows)
Common Mistakes & Troubleshooting
| Configuration Failure | Operational Symptom | Remediation Protocol |
|---|---|---|
| Legacy upgrades fail to start | Upgrading to MySQL 8 fails with Unknown variable 'query_cache_size'. | Remove old query cache directives from your config. |
| Performance regression after disabling | Response time gets worse after removing query cache settings. | Confirm OPcache is configured and consider object caching/page caching rather than DB query caching. |