Magento 2 Database Optimization

MySQL 8.0 reached its official end of support on April 30, 2026. According to Adobe's system requirements documentation, Adobe Commerce versions 2.4.7 and earlier will not provide compatibility or support for any MySQL versions released after MySQL 8.0 from that date forward. That is not a distant concern: it is a present one. If your Magento 2 store still runs MySQL 8.0, you need a migration plan now, not at your next review cycle.

The database is consistently the most overlooked performance variable in Magento 2 stores. Frontend teams chase Core Web Vitals scores, cache configurations get tweaked repeatedly, and CDNs get added to the stack. Meanwhile, the underlying MySQL instance runs on its default settings from the year the server was provisioned. Most production Magento stores have never had their InnoDB buffer pool size properly set, have never had their slow query log enabled, and carry several hundred megabytes of log table data that serves no operational purpose. These are not edge cases. They are standard conditions on stores that process real revenue.

This guide pulls directly from Adobe's official Performance Best Practices documentation and the MySQL 8.0 Reference Manual to give you configuration values that are grounded in primary sources, not secondhand blog summaries. You will find diagnostic commands you can run today, specific my.cnf parameters with the rationale behind each setting, a cleanup sequence for bloated log tables, and a comparison of MySQL 8.4, MariaDB 11.4, and Percona for Magento 2.4.8 deployments.

Why Your Magento 2 Database Is the Biggest Performance Variable?

Every product load, category browse, cart action, and checkout step in a Magento 2 store generates database queries. The platform's EAV (Entity-Attribute-Value) data model means that even a single product display can trigger dozens of individual queries across multiple tables. When the database is unhealthy, every part of the storefront degrades: page load times climb, Time to First Byte (TTFB) worsens, and the admin panel becomes sluggish enough that daily operations slow down.

Caching helps, but it does not replace a well-tuned database. Varnish and Redis serve cached responses, which reduces the total query load. However, cache misses, admin operations, checkout processes, and any uncacheable page still hit MySQL directly. A poorly configured InnoDB instance with no appropriate buffer pool sizing will make those uncached requests noticeably slow, regardless of what caching stack sits in front of it.

The practical result is this: a Magento 2 store can have Varnish, Redis, and a CDN all correctly configured and still have a slow admin panel, slow category pages on first load, and slow checkout. The common thread is almost always the database. Fixing it tends to produce larger, more consistent improvements than any other single change.

The 2026 Database Version Reality Check

Here is the 2026 database versio reality you need to know.

MySQL 8.0 is End-of-Life: What This Means Right Now

MySQL 8.0 ended general availability support on April 30, 2026. The official Adobe system requirements page states explicitly that Adobe Commerce versions 2.4.4 through 2.4.7 will not provide compatibility or support for MySQL versions released after 8.0. Adobe strongly advises all on-premises customers on those versions to migrate their database servers to a compatible MariaDB version.

For Magento 2.4.8, the current stable release as of 2026, the supported database options are MySQL 8.4 LTS and MariaDB 11.4. MySQL 8.4 is the tested and recommended version. MySQL 8.0 still functions but sits outside the tested configuration boundary. Looking ahead, the Magento 2.4.9 beta (released March 2026) formally drops both MySQL 8.0 and MariaDB 10.6. Planning your database upgrade alongside your Magento version upgrade is now a requirement, not an optional housekeeping task.

If you are unsure which database version your store runs, connect to your server and run:

mysql --version

Or from within MySQL:

SELECT VERSION();

Cross-reference the result with the Adobe system requirements matrix for your Magento version before taking any other optimization step.

MySQL 8.4 LTS vs. MariaDB 11.4 for Magento 2.4.8

Both MySQL 8.4 and MariaDB 11.4 are fully supported for Magento 2.4.8. The choice matters less than picking one and configuring it properly. That said, there are practical differences worth knowing.

MySQL 8.4 is the straightforward upgrade path for stores currently on MySQL 8.0. According to Adobe's upgrade prerequisites guide, upgrading from 8.0 to 8.4 requires setting restrict_fk_on_non_standard_key to OFF in the MySQL configuration file and restarting the server. That is a manageable one-step change.

MariaDB 11.4 offers additional storage engine options (including Aria), horizontal replication support via Galera Cluster, and a query cache that was removed from MySQL in version 8.0. Adobe's MySQL guidelines for Commerce note that reindexing on MariaDB 10.4 and 10.6 is slower than on previous versions, and recommend specific configuration parameters to compensate. Plan for testing after any upgrade to either platform.

Percona Server remains community-tested with Magento but is not listed in Adobe's official supported configuration matrix for 2.4.8. High-traffic stores that have previously invested in Percona tooling can continue using it, but new deployments should default to MySQL 8.4 LTS for cleaner support coverage.

MySQL 8.4 vs. MariaDB 11.4 vs. Percona: Quick Reference

Feature

MySQL 8.4 LTS

MariaDB 11.4 LTS

Percona Server 8.0

Magento 2.4.8 support

Full (recommended)

Full (supported)

Partial (community tested)

Magento 2.4.9 support

Full (recommended)

Full (supported)

Not listed in Adobe docs

MySQL 8.0 EOS impact

Upgrade path: 8.0 to 8.4

Upgrade path: 10.6 to 11.4

Follow MySQL upstream

Reindex performance

Baseline

Slower on 10.4/10.6; set optimizer switches

Similar to MySQL

In-memory tech (Aria)

No

Yes (Aria storage engine)

No

Query cache (deprecated)

Removed in 8.0

Available (query-cache-type)

Removed in 8.0

Notable users

Most shared hosts

Nokia, Red Hat, Samsung

Facebook, Netflix, Adobe

Community size

Largest

Large

Smaller, specialized

Source: Adobe Experience League system requirements and MySQL official documentation.

Diagnosing Database Bottlenecks Before You Tune Anything

There is a temptation to start adjusting configuration values immediately. Resist it. Tuning a database without a baseline measurement means you cannot verify whether a change helped, hurt, or did nothing. Take three diagnostic steps first.

Enabling MySQL's Slow Query Log

The slow query log is MySQL's built-in tool for identifying queries that exceed a time threshold you define. Run these commands to activate it during a live session (they take effect immediately without a restart):

SET GLOBAL slow_query_log = 'ON';

SET GLOBAL long_query_time = 1;

SET GLOBAL slow_query_log_file = '/var/log/mysql/mysql-slow.log';

Setting long_query_time to 1 captures every query that takes more than one second. For a production Magento store, one second is already too long. Once you have identified the offending queries, you can use EXPLAIN on each one to understand the execution plan and determine whether an index would help or whether the query itself needs to be rewritten.

To make the slow query log persistent across restarts, add these lines to your my.cnf or my.ini under the [mysqld] section:

slow_query_log = 1 long_query_time = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log

Using SHOW ENGINE INNODB STATUS

InnoDB exposes a detailed internal status report that every Magento DBA should know. Run it from the MySQL monitor:

SHOW ENGINE INNODB STATUS\G

The output is dense, but focus on two sections. First, look at BUFFER POOL AND MEMORY. You want to see a buffer pool hit rate above 99%. A rate below that means InnoDB is regularly fetching pages from disk rather than from memory, which is the single most common cause of slow query performance on well-indexed tables.

Second, look at the TRANSACTIONS section. Queries that appear to be running for several minutes without completing usually indicate a lock wait issue, where one transaction is blocking another. This is more common in Magento than most admins realize, particularly during index runs or bulk import operations.

Running MySQLTuner for a Configuration Snapshot

MySQLTuner is an open-source Perl script maintained by Major Hayden that analyzes a running MySQL instance and produces a prioritized list of configuration recommendations. It is not a substitute for understanding what you are changing, but it is a fast way to identify obvious misconfigurations on a new or inherited server:

wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl perl mysqltuner.pl

Pay attention to the recommendations flagged as critical before the ones marked as suggestions. On most default Magento installations, the first critical flag is always the buffer pool size.

InnoDB Buffer Pool: The Most Impactful Single Setting

The MySQL 8.0 Reference Manual describes the InnoDB buffer pool as "an area in main memory where InnoDB caches table and index data as it is accessed." The manual's guidance is direct: on dedicated database servers, up to 80% of physical memory is often assigned to the buffer pool. The larger the buffer pool, the more InnoDB acts like an in-memory database, reading data from disk once and then serving subsequent reads from RAM.

For Magento 2 specifically, Adobe's official performance best practices documentation specifies that each buffer pool instance should be at least 1 GB. This is a hard minimum for any store with a meaningful product catalog. The default value of 128 MB is adequate for development environments and nothing else.

Calculating the Right Buffer Pool Size

On a server dedicated to the MySQL database, the starting calculation is straightforward: take 70 to 80% of total RAM and assign it to innodb_buffer_pool_size. On a shared server where MySQL runs alongside the web application, use 50 to 60% as the starting point. The remaining memory must cover the operating system, PHP-FPM workers, and other services.

A 16 GB dedicated database server should have a buffer pool of approximately 12 GB. A 32 GB dedicated server should have a buffer pool between 22 and 26 GB. The MySQL documentation on buffer pool sizing notes that the total buffer pool size must be a multiple of innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances to avoid automatic size adjustment.

innodb_buffer_pool_size = 12G   # For 16GB dedicated DB server

Buffer Pool Instances

Adobe's software recommendations set the default for innodb_buffer_pool_instances to 8. This is intentional: multiple pool instances reduce contention when many threads attempt to access the buffer pool simultaneously. For a Magento store under concurrent load, eight instances is a reasonable starting point. The MySQL documentation recommends that each instance be at least 1 GB to operate efficiently.

innodb_buffer_pool_instances = 8

Verifying Buffer Pool Hit Rate

After updating the buffer pool size and allowing the instance to warm up (which takes some time on restart), verify the hit rate using the Performance Schema:

SELECT variable_name, variable_value
FROM performance_schema.global_status
WHERE variable_name IN (
    'Innodb_buffer_pool_reads',
    'Innodb_buffer_pool_read_requests'
);

Divide Innodb_buffer_pool_reads (physical disk reads) by Innodb_buffer_pool_read_requests (total read requests). Subtract from 1 and multiply by 100 to get the hit rate percentage. Anything below 99% on a store with a correctly sized buffer pool indicates either that the pool is still too small or that large table scans (such as those triggered by full reindexes) are flushing frequently accessed pages out of cache.

Critical my.cnf Settings for Magento 2 Stores

The following configuration parameters come directly from Adobe's performance best practices and the MySQL 8.0 reference manual. These are the settings that have the most material impact on Magento performance. Add or update them in the [mysqld] section of your my.cnf file.

[mysqld] # Buffer pool: set to 70-80% of RAM on a dedicated DB server innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8 # Log file size: larger logs reduce checkpoint frequency innodb_log_file_size = 512M
# Flush method: O_DIRECT avoids double-buffering with the OS innodb_flush_method = O_DIRECT
# Flush at commit: 2 gives better write performance (slight durability trade-off)
# For payment-critical stores, use 1 (default) and accept the performance cost innodb_flush_log_at_trx_commit = 2
# Connections: match to total PHP-FPM workers across all web nodes
# Adobe recommends 300 for small, 1000 for medium environments max_connections = 300
# Thread concurrency: 2 x (CPU cores + disk spindles)
# 0 = unlimited (let InnoDB decide, often better on modern hardware) innodb_thread_concurrency = 0
# Large imports and attribute sets max_allowed_packet = 64M
# Temporary tables for indexing and catalog rules tmp_table_size = 64M max_heap_table_size = 64M

A note on innodb_flush_log_at_trx_commit: setting it to 2 means that InnoDB flushes the log buffer to the OS file cache after each transaction commit, but does not force the OS to flush to disk. In the event of an OS crash (not a MySQL crash), you could lose up to one second of transactions. For most Magento stores, the performance gain is worth this trade-off. For stores handling large payment volumes where data integrity is paramount, leave this at the default value of 1.

For the catalog rules indexer specifically, Adobe's advanced setup guide notes that stores with a large number of catalog rules should allocate more memory to TMP_TABLE_SIZE and MAX_HEAP_TABLE_SIZE. Stores with complex promotional structures and thousands of rules may need these values at 256 MB or higher.

Magento 2 Index Management and Database Efficiency

Magento 2 uses indexers to pre-compute data that would be expensive to calculate on every page load: flat catalog tables, price indexes, stock availability, search index data, and more. How these indexers run has a direct impact on both database load and storefront performance.

Schedule Mode vs. Save Mode

Magento 2 indexers can run in two modes. "Update on Save" triggers reindexing immediately when you save a product, category, or price rule in the admin. "Update by Schedule" writes changes to a changelog table and processes them on a schedule via cron. For any store with more than a few hundred products, Update by Schedule is the correct choice. Saving a product that triggers an immediate full price reindex on a 50,000-SKU catalog will block the save operation for minutes.

Check the current mode for all indexers:

bin/magento indexer:show-mode

Switch all indexers to schedule mode:

bin/magento indexer:set-mode schedule

Note: As of Magento 2.4.8, all new indexers default to schedule mode. The Customer Grid indexer, which previously only supported Update on Save, now supports both modes and defaults to Update by Schedule after upgrading to 2.4.8.

Running Reindex from CLI

When you need to force a full reindex (after a bulk import, after a migration, or after disabling and re-enabling a flat catalog setting), always run reindexing via CLI, not through the admin panel:

bin/magento indexer:reindex

To reindex a specific indexer rather than everything:

bin/magento indexer:reindex catalog_product_price

Run reindexing operations during off-peak hours. A full catalog reindex on a large product base locks tables and can noticeably degrade storefront response times while it runs. Schedule it for the lowest-traffic window your store has.

Database Table Cleanup: Removing What Slows You Down

Magento 2 accumulates data in log and reporting tables that grows indefinitely unless you clear it. On a store that has been running for two or three years with no cleanup, these tables can account for several gigabytes of storage and meaningfully slow down queries that have nothing to do with their content. The data in these tables serves no operational purpose once it is older than a few weeks.

Log Tables That Bloat Over Time

The following tables are safe to truncate on a running production store. Always take a database backup before running TRUNCATE operations.

TRUNCATE report_event; TRUNCATED report_viewed_product_index; TRUNCATE report_compared_product_index; TRUNCATE catalog_compare_item; 
TRUNCATE customer_visitor; TRUNCATE quote;

The quote table deserves particular attention. Magento stores a database row for every guest cart created on the storefront. On a high-traffic store with no cleanup, this table can accumulate millions of rows representing abandoned sessions from years ago. Truncating it removes no active customer orders or live carts (those are in the sales_order tables, not quote), but requires confirming that no active coupons or quote-linked promotions are mid-session.

Magento provides a built-in mechanism to manage this automatically. In the admin panel, go to Stores > Configuration > Advanced > System > Save Log, and set the log entry lifetime values. The system will clean these tables on the configured schedule via cron.

Automating Cleanup with CRON

Manual cleanup is better than no cleanup, but it depends on someone remembering to do it. The correct solution is scheduled automation via Magento's cron system. Two things need to work for this to happen: the Magento cron must be configured correctly on the server, and the cleanup jobs must be set to run on a schedule that prevents tables from re-bloating between runs.

Verify your cron setup from the server command line:

crontab -l

You should see entries for both bin/magento cron:run and bin/magento setup:cron:run. If they are missing, the scheduled cleanup will not run. Add them if absent, or use MageDelight's Magento 2 CRON Scheduler to gain a visual dashboard in the admin panel showing which jobs are running, which have failed, and which are pending. This removes the need for server-level access to verify cron health.

For stores where cron scheduling has been neglected, the cron_schedule table itself can balloon. If you see millions of rows in it, clean it with:

DELETE FROM cron_schedule
WHERE status != 'pending'
AND scheduled_at < NOW() - INTERVAL 2 DAY;

OpenSearch Replaces MySQL Search: Do Not Overlook This

Many older guides on Magento 2 database optimization include recommendations for optimizing MySQL-based catalog search. This is no longer relevant. Adobe's release notes for Magento 2.4.0 removed the MySQL catalog search engine from the platform entirely. As of 2.4.0, all Magento stores must use either Elasticsearch or OpenSearch for catalog search.

For Magento 2.4.8, OpenSearch is the recommended search engine. Elasticsearch 7 and 8 are still supported in 2.4.6 and 2.4.7 but are deprecated in favor of OpenSearch. Magento 2.4.9 removes Elasticsearch support entirely. Configuring OpenSearch offloads all search queries from MySQL to a dedicated search engine using inverted indexing technology, which returns product IDs instantly without touching the main product tables. This reduces database query volume noticeably on stores with active search traffic.

If your store still shows "mysql" as the search engine in Stores > Configuration > Catalog > Catalog Search, you are running an outdated search configuration even if your Magento version nominally supports it. Migrate to OpenSearch. The database performance improvement is secondary to the search quality improvement, but both are real.

MySQL vs. MariaDB vs. Percona for Magento 2

The comparison table earlier in this guide covers the version-level differences. At the architecture level, the choice comes down to what your team can support and what your hosting environment provides.

MySQL 8.4 is the safest choice for stores where the hosting environment is managed or where the team has limited database administration experience. It is the version Adobe tests against most thoroughly, it has the largest community of documentation and tooling, and it has the most straightforward upgrade path from MySQL 8.0.

MariaDB 11.4 makes sense for teams that need the Aria storage engine for specific use cases, want Galera Cluster for multi-master replication, or are already on a MariaDB-based managed cloud where upgrading to 11.4 is a version bump rather than a platform change. Notable MariaDB deployments in the enterprise space include Red Hat and Samsung, and the MariaDB Foundation's community support model means security patches tend to appear quickly. One critical note from  Adobe's MySQL guidelines: Magento only uses MySQL features compatible with MariaDB, but MariaDB may not be compatible with all MySQL features. Research compatibility before using MySQL-specific features in custom modules.

Percona Server is the right call for teams that already have internal Percona expertise, particularly those managing high-traffic stores where Percona's XtraBackup tooling and fine-grained performance diagnostics add value. Facebook, Netflix, and Adobe itself are among Percona's noted users. For new installations without existing Percona investment, MySQL 8.4 is simpler to set up and maintain within Adobe's support matrix.

Monitoring Your Magento 2 Database Continuously

A one-time optimization effort degrades over time. Tables re-bloat, query patterns change as the product catalog grows, and new extensions introduce queries that perform well at low load and poorly at scale. Continuous monitoring is what separates a store that stays fast from one that requires emergency intervention every six months.

At the MySQL level, the Performance Schema (enabled by default in MySQL 8.0 and later) provides detailed query-level statistics. Pair it with a tool like Percona Monitoring and Management (PMM) or New Relic to surface slow queries automatically before they become customer-facing problems.

At the Magento level, MageDelight's System Health Monitor provides a centralized admin dashboard that evaluates the database, cache, cron, PHP environment, and filesystem in one view. It uses optimized queries and controlled system calls designed to avoid adding load to the server it monitors. For teams that do not have dedicated infrastructure tooling, this is a practical way to surface database and cron issues from inside the Magento admin without needing SSH access or external APM tooling.

Set a recurring review on your calendar: check the slow query log monthly, verify buffer pool hit rate quarterly, and run a table size audit twice a year. On a fast-growing store, quarterly table audits are worth doing. The information_schema.tables view gives you a quick size overview:

SELECT table_name,
       ROUND(data_length/1024/1024, 2) AS data_mb,
       ROUND(index_length/1024/1024, 2) AS index_mb
FROM information_schema.tables
WHERE table_schema = 'your_magento_db'
ORDER BY data_length DESC
LIMIT 20;

The tables at the top of this list are the first place to investigate when performance degrades unexpectedly.

Advanced: Read/Write Splitting and Database Replication

For stores with sustained high traffic, separating read queries from write queries across multiple database servers can significantly reduce load on the primary. Magento 2 supports MySQL replication natively. Adobe's Commerce (paid) edition historically included a split database feature that distributed checkout, sales, and catalog data across separate master databases. However, Adobe deprecated that split database feature in version 2.4.2. New installations should use a single master database with read replicas rather than the split database approach.

Setting up a read replica involves configuring a slave MySQL server that replicates from the master asynchronously. Magento's ResourceConnections class can route read queries to slave instances. The Adobe Commerce database replication guide covers the env.php configuration required. MySQL replication is asynchronous by default, which means slave servers do not need to be permanently connected to receive updates and the master is not blocked by replication lag.

For stores on Adobe Commerce (not Open Source), where you are considering read replicas, test your custom extensions for read/write compatibility first. Extensions that write directly to the database (bypassing Magento's service layer) will not function correctly in a replicated setup. Check with extension developers before implementing replica routing in production.

Pair database replication with Redis for cache and session storage, which Adobe recommends for all multi-node setups. Adobe's performance documentation notes that stores handling hundreds to thousands of simultaneous requests may need a network channel of up to 1 Gbit between web nodes and the Redis server. The database and cache layers are complementary: an optimized database reduces query load, and an optimized cache reduces the total number of queries that reach the database at all.

Frequently Asked Questions

Here are answers to the most common questions about Magento 2 database optimization and MySQL performance tuning.

1. What Is The Fastest Way To Check If My Magento 2 Database Needs Optimization?

Run SHOW ENGINE INNODB STATUS\G and look at the buffer pool hit rate in the BUFFER POOL AND MEMORY section. If it is below 99%, the buffer pool is too small relative to your working data set. Also check the total size of your quote, report_event, and cron_schedule tables using the information_schema query provided above. If any of them exceed 500 MB, cleanup is overdue.

2. Can I Change Innodb_buffer_pool_size Without Restarting Mysql?

Yes. MySQL 8.0 and later support dynamic buffer pool resizing via SET GLOBAL innodb_buffer_pool_size = [value];. The operation resizes in chunks and can take some time on large pools. The MySQL documentation notes that the resize does not start until all active transactions are completed, and that new transactions must wait until the resize finishes. For minimal disruption, make this change during a low-traffic window even though a restart is not required.

3. Will Disabling Flat Catalog Tables Hurt Or Help Performance On Magento 2.4.X?

Disable flat catalog tables. On Magento 2.1 and later, Adobe's official guidance is to turn off flat catalog for both categories and products. With flat tables and indexers enabled on modern Magento versions, you risk performance degradation and indexing issues rather than the speed gains the feature offered on older versions. Navigate to Stores > Configuration > Catalog and set both "Use Flat Catalog Category" and "Use Flat Catalog Product" to No.

4. How Do I Know If A Third-Party Extension Is Causing Database Performance Issues?

Enable the slow query log with a threshold of 0.5 seconds (lower than the 1-second threshold used for general monitoring). After a traffic period, open the log and group queries by table. Queries against tables named after a specific extension's vendor prefix (for example, tables starting with amasty_, mirasvit_, or other vendor names) point directly to that extension. Use EXPLAIN on those specific queries to determine whether indexes are missing or queries are poorly structured.

5. Should I Use Mysql 8.4 Or Mariadb 11.4 For A New Magento 2.4.8 Installation?

Default to MySQL 8.4 LTS unless you have a specific reason to choose MariaDB. MySQL 8.4 is Adobe's primary tested configuration, has the widest hosting support, and requires no compatibility research for MySQL-specific features you might use in custom code. MariaDB 11.4 is a valid choice if your hosting environment defaults to it or if you need MariaDB-specific capabilities like Galera Cluster.

Database Optimization Is an Ongoing Practice, Not a One-Time Fix

The configuration changes described in this guide are not a one-time project. A properly sized buffer pool today will be undersized in eighteen months if your catalog doubles. Log tables that were clean after a truncation will be bloated again in six months without scheduled cleanup. Slow queries introduced by a new extension will not surface until the catalog grows to a size that exposes their inefficiency.

Start with the version check: confirm you are on MySQL 8.4 or MariaDB 11.4. Then set the buffer pool correctly using the 70-80% RAM formula from the MySQL documentation. Enable the slow query log and spend one session reviewing what it surfaces. Clean the bloated log tables and verify that your cron jobs are actually running to keep them clean. Run the reindexers on schedule mode if they are not already.

That sequence addresses the most common and most impactful database problems on Magento 2 stores. If performance issues persist after those changes, the next layer is query-level investigation: identifying which specific queries are slow, what tables they touch, and whether custom extensions are responsible.

For ongoing monitoring without the overhead of setting up external APM tooling, the MageDelight System Health Monitor and CRON Scheduler provide visibility into database health and background job execution directly from the Magento admin panel, without requiring server-level access for routine checks. For deeper performance work, MageDelight's Magento Performance Audit service covers code, database, and infrastructure-level diagnosis as a managed engagement.