MySQL Configuration Tuning
AdvancedKey InnoDB variables: innodb_buffer_pool_size (60–80% of RAM), innodb_log_file_size, max_connections, thread_cache_size — benchmark with sysbench before and after tuning.
Overview
MySQL performance tuning centers on a small set of high-impact configuration variables. The most important is innodb_buffer_pool_size — the in-memory cache for InnoDB data and index pages. A well-sized buffer pool eliminates most disk I/O; the hit ratio should exceed 99% in production. Other critical settings: innodb_redo_log_capacity (write throughput and crash recovery speed), max_connections (connection overhead), thread_cache_size (reduce thread creation overhead), and query_cache (removed in 8.0 — use application-level caching instead). Always benchmark before and after tuning with a representative workload using sysbench or your own workload replay.
InnoDB buffer pool — the most important setting
The buffer pool caches data and index pages in memory — the larger it is, the more data is served from RAM rather than disk. Set it to 60–80% of total RAM (leave room for OS, connections, and temp tables). On machines with > 1 GB RAM, use multiple buffer pool instances (innodb_buffer_pool_instances) to reduce mutex contention. Monitor the buffer pool hit ratio — it should be > 99%.
# my.cnf — InnoDB buffer pool configuration
[mysqld]
# Set to 60-80% of available RAM
# Example: 16 GB server → 10-12 GB buffer pool
innodb_buffer_pool_size = 10G
# Multiple instances reduce mutex contention (1 per 1 GB)
innodb_buffer_pool_instances = 10
# Warm buffer pool on restart (avoids cold-start I/O storm)
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON
# Monitor buffer pool hit ratio
SELECT
(1 - (SELECT variable_value FROM performance_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_reads') /
(SELECT variable_value FROM performance_schema.global_status
WHERE variable_name = 'Innodb_buffer_pool_read_requests')
) * 100 AS buffer_pool_hit_ratio_pct;
-- Target: > 99%
# Shortcut via sys schema
SELECT * FROM sys.innodb_buffer_stats_by_schema
ORDER BY pages_allocated DESC LIMIT 10;Redo log, connections, and write performance
The InnoDB redo log (write-ahead log) determines crash recovery speed and write throughput. Larger redo log = higher write throughput but slower crash recovery. MySQL 8.0.30+ uses innodb_redo_log_capacity (replaces the old innodb_log_file_size). max_connections limits concurrent connections (each uses ~1 MB RAM). thread_cache_size caches idle threads to avoid OS thread creation overhead.
# my.cnf — write performance and connection tuning
[mysqld]
# Redo log capacity (MySQL 8.0.30+)
innodb_redo_log_capacity = 4G # larger = better throughput, slower recovery
# Older MySQL: innodb_log_file_size = 1G (redo log = 2 × log_file_size)
# Durability vs performance trade-off
innodb_flush_log_at_trx_commit = 1 # safest: flush to disk on every commit
# = 2: flush to OS buffer on commit (lose up to 1s on crash)
# = 0: flush every second (lose up to 1s on crash + OS crash)
sync_binlog = 1 # flush binlog to disk on every commit
# Connection tuning
max_connections = 500 # max concurrent connections
thread_cache_size = 50 # cache 50 idle threads (reduce thread creation)
wait_timeout = 600 # close idle connections after 10 min
interactive_timeout = 600
# I/O method (Linux) — O_DIRECT bypasses OS page cache (reduces double buffering)
innodb_flush_method = O_DIRECT
# Check current connection overhead
SHOW STATUS LIKE 'Threads_created'; # high = thread_cache too small
SHOW STATUS LIKE 'Connections'; # total connection attempts
SHOW STATUS LIKE 'Max_used_connections'; # peak simultaneous connectionsQuery optimiser settings and temp table configuration
The optimiser uses statistics to choose query plans. optimizer_switch controls which optimisation features are active. tmp_table_size and max_heap_table_size control in-memory temp table size — if a temp table exceeds this, it spills to disk (visible as Created_tmp_disk_tables in SHOW STATUS). Increase these values if EXPLAIN shows "Using temporary; Using filesort" frequently.
# my.cnf — temp tables and optimizer settings
[mysqld]
# Temp table memory limits
tmp_table_size = 256M # max in-memory temp table size
max_heap_table_size = 256M # must match tmp_table_size
# Join buffer for non-indexed joins
join_buffer_size = 4M # per-join allocation (not global pool)
# Sort buffer
sort_buffer_size = 4M # per-sort allocation
# Key buffer (MyISAM only — for InnoDB, use buffer pool)
key_buffer_size = 32M
# Check if temp tables are spilling to disk
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables'; # spilled to disk
SHOW GLOBAL STATUS LIKE 'Created_tmp_tables'; # total temp tables
# Ratio: disk / total > 10% → increase tmp_table_size
# EXPLAIN to check sorts and temp tables
EXPLAIN SELECT customer_id, COUNT(*) FROM orders
GROUP BY customer_id ORDER BY COUNT(*) DESC;
-- "Using temporary; Using filesort" = memory temp table + sort
-- Increase tmp_table_size or add a covering indexKey Points to Remember
- 1innodb_buffer_pool_size is the single most impactful setting — set to 60–80% of RAM; buffer pool hit ratio should be > 99%
- 2innodb_redo_log_capacity controls write throughput — larger = faster writes, but longer crash recovery on restart
- 3innodb_flush_log_at_trx_commit=1 + sync_binlog=1 is the safest durability setting, at a throughput cost
- 4max_connections × ~1 MB RAM = total memory for connections — do not set to 10,000 on a 16 GB server
- 5tmp_table_size controls when temp tables spill to disk — monitor Created_tmp_disk_tables / Created_tmp_tables ratio
- 6Always benchmark with sysbench or application workload replay before and after tuning to verify improvement
Interview Questions
Sign in to ask AriaWhat is innodb_buffer_pool_size and how would you size it for a 32 GB server running only MySQL?
What do the different values of innodb_flush_log_at_trx_commit mean and what are the trade-offs?
How would you detect if temp tables are spilling to disk and what configuration change helps?
Why should max_connections not simply be set to a very large number?
What is the buffer pool hit ratio and what does a low value (< 95%) indicate?
Ask Aria about MySQL Configuration Tuning
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.