The InnoDB buffer pool caches table and index pages and holds modified pages before they are flushed. A larger pool can reduce storage reads, but an oversized pool can force the operating system to reclaim memory or swap, causing worse latency than a smaller, stable configuration. There is no universal percentage that is correct for every MySQL host.
- Budget memory for MySQL's global allocations, peak connection and query workspaces, other processes, and the operating system before sizing the pool.
- Measure changes in physical reads, request latency, dirty-page pressure, and host memory; a hit ratio has no universal pass mark.
- Online resize is useful but can briefly block work and shrinking can force page eviction and I/O.
- Buffer-pool dump/load can reduce cold-start impact, but it does not replace controlled restart testing.
Build a memory budget
Start with installed RAM, then reserve memory for the OS and filesystem, monitoring and backup agents, co-located services, MySQL's non-buffer-pool global allocations, and the peak—not average—memory used by concurrent sessions. Sorts, joins, temporary tables, connection buffers, Performance Schema, replication, and backup work can all add pressure. Keep enough headroom for unusual concurrency and maintenance.
On a host dedicated to MySQL, innodb_dedicated_server=ON can calculate selected InnoDB memory and log settings. For the buffer pool, MySQL 8.4 uses 128 MB on hosts with at most 1 GB detected memory, 50% between 1 GB and 4 GB, and 75% above 4 GB. Do not enable this automatic mode on a shared host; it assumes MySQL can use most server resources.
Inspect the active configuration
SHOW GLOBAL VARIABLES WHERE Variable_name IN (
'innodb_buffer_pool_size',
'innodb_buffer_pool_instances',
'innodb_buffer_pool_chunk_size',
'innodb_buffer_pool_dump_at_shutdown',
'innodb_buffer_pool_load_at_startup',
'innodb_buffer_pool_dump_pct',
'innodb_old_blocks_pct',
'innodb_old_blocks_time'
);For multiple buffer-pool instances, MySQL requires each instance to be at least 1 GB and supports up to 64 instances. Multiple instances can reduce contention on large pools, but “one instance per GB” is not an official sizing rule. Keep the default unless mutex evidence and repeatable load tests justify a change.
Measure cache misses as deltas
SHOW GLOBAL STATUS WHERE Variable_name IN (
'Innodb_buffer_pool_read_requests',
'Innodb_buffer_pool_reads',
'Innodb_buffer_pool_pages_data',
'Innodb_buffer_pool_pages_dirty',
'Innodb_buffer_pool_pages_free',
'Innodb_buffer_pool_wait_free',
'Innodb_data_reads',
'Innodb_data_read'
);Innodb_buffer_pool_read_requests counts logical requests and Innodb_buffer_pool_reads counts reads that could not be satisfied from the pool. A cache-hit estimate over an interval is 1 - delta(reads) / delta(read_requests). Use two samples around a representative workload because global counters are cumulative. A high ratio can coexist with a small set of latency-critical misses, and a lower ratio can be acceptable for scans or a working set larger than RAM.
Correlate the deltas with query latency, storage read latency and throughput, free/available host memory, swap activity, dirty-page percentage, flush pressure, and Innodb_buffer_pool_wait_free. Tune a bottleneck, not a standalone ratio.
Resize in controlled steps
innodb_buffer_pool_size is dynamic. The resulting size is aligned to the buffer-pool chunk size multiplied by the number of instances, so the effective value can differ from the request. The following is an illustrative 8 GiB target, not a general recommendation:
SET GLOBAL innodb_buffer_pool_size = 8589934592;
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_resize_status';Use SET PERSIST only after the trial is accepted and the configuration ownership model permits MySQL's persisted-variables file. Otherwise update the managed configuration through the normal deployment system.
Allocation and deallocation can briefly block operations in critical paths. Shrinking a pool can evict pages and increase reads or flushing. Change one step at a time during an observed window, monitor resize status and latency, and keep a rollback value that fits the memory budget.
Warm-up after restart
MySQL 8.4 enables innodb_buffer_pool_dump_at_shutdown and innodb_buffer_pool_load_at_startup by default. The dump stores page identifiers, not page contents; startup uses that list to read selected pages back into the pool. The default innodb_buffer_pool_dump_pct is 25, representing the most recently used portion of each pool.
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_dump_status';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_load_status';
-- Controlled manual operations:
SET GLOBAL innodb_buffer_pool_dump_now = ON;
SET GLOBAL innodb_buffer_pool_load_now = ON;Do not trigger a manual load during a latency-sensitive period without testing: it creates storage reads. Validate restart behavior with real readiness checks. A process that accepts TCP connections can still be cold for the workload.
Reduce scan pollution carefully
InnoDB divides the LRU into old and new sublists so a large scan does not immediately displace every hot page. innodb_old_blocks_pct controls the old sublist share. innodb_old_blocks_time is 1000 milliseconds by default, meaning a page must remain in the old sublist for that interval before another access can promote it. Setting it to 1000 is therefore not an increase on a default MySQL 8.4 server.
Change these settings only when workload evidence shows large scans displacing useful pages. Query plans and indexes are usually the first place to fix accidental scans. A deliberate analytical scan may be better isolated from an OLTP server.
A safe tuning loop
- Capture a peak-period baseline: latency distribution, throughput, physical-read deltas, dirty pages, storage behavior, available memory, and swap.
- Identify whether misses or flushing actually constrain the user-facing workload.
- Model memory under worst credible concurrency, including maintenance.
- Change one variable or pool-size step and observe a complete workload cycle.
- Persist only a repeatable improvement with safe memory headroom.
- Re-test restart warm-up, backup work, replication, and failover behavior.
Official primary sources
- InnoDB buffer pool optimization
- Buffer pool configuration and online resize
- Multiple buffer pool instances
- InnoDB dedicated server mode
- MySQL 8.4 InnoDB system variables
- InnoDB monitoring
Working with JusDB on MySQL performance
JusDB helps teams build memory budgets, measure buffer-pool behavior, run controlled resize tests, and validate warm-up and failover performance under production-shaped load.