MySQL

MySQL InnoDB Redo Log Tuning: Sizing for Production Write Throughput

The InnoDB redo log default of 100MB is dangerously undersized for production. Learn to measure your write throughput, size innodb_redo_log_capacity correctly, and monitor checkpoint pressure before write stalls occur.

JusDB Team
October 21, 2025
9 min read
188 views

Your MySQL server absorbed 50,000 writes per second during the flash sale — then spent 45 minutes catching up on checkpointing afterward. InnoDB's redo log is the gatekeeper for write throughput, and most deployments leave it dramatically under-configured. Here's the complete tuning guide.

TL;DR
  • MySQL 8.0.30+ uses a dynamic redo log with automatic sizing — the old innodb_log_file_size is deprecated
  • Set innodb_redo_log_capacity to 4–8x your peak writes-per-second throughput (in bytes)
  • Monitor Innodb_redo_log_current_lsn vs Innodb_checkpoint_age to catch redo log pressure
  • Undersized redo log forces frequent checkpoints, causing 30–50% write throughput reduction

How InnoDB's Redo Log Works

InnoDB writes all changes first to the redo log (write-ahead log) before modifying data pages in the buffer pool. This allows InnoDB to handle crash recovery and defer expensive random I/O to background checkpointing. The redo log is circular: when it fills up, InnoDB must flush dirty pages from the buffer pool to disk (a checkpoint) to make space.

MySQL 8.0.30+: Dynamic Redo Log

sql
-- Check current redo log configuration
SHOW VARIABLES LIKE 'innodb_redo%';

-- innodb_redo_log_capacity: total redo log size (MySQL 8.0.30+)
-- Default: 104857600 (100MB) -- FAR TOO SMALL for production

-- Set via my.cnf:
-- innodb_redo_log_capacity = 4294967296  # 4GB

-- Check redo log pressure
SHOW STATUS LIKE 'Innodb_redo_log%';
SHOW STATUS LIKE 'Innodb_checkpoint%';

Sizing the Redo Log

Measuring Current Redo Log Throughput

sql
-- Measure redo log write rate over 60 seconds
SELECT variable_value INTO @lsn_start
FROM performance_schema.global_status
WHERE variable_name = 'Innodb_redo_log_current_lsn';

SELECT SLEEP(60);

SELECT variable_value INTO @lsn_end
FROM performance_schema.global_status
WHERE variable_name = 'Innodb_redo_log_current_lsn';

SELECT (@lsn_end - @lsn_start) / 60 AS redo_bytes_per_second,
       (@lsn_end - @lsn_start) / 60 * 3600 AS redo_bytes_per_hour,
       FORMAT((@lsn_end - @lsn_start) / 60 / 1024 / 1024, 2) AS redo_mb_per_second;

-- Rule of thumb: redo log capacity = 60-90 minutes of peak write throughput
-- If peak is 50 MB/s: capacity = 50 * 60 * 60 = 180GB (use 8-16GB in practice)
Write Throughput (peak)Recommended innodb_redo_log_capacity
Under 10 MB/s1–2 GB
10–50 MB/s4–8 GB
50–200 MB/s8–32 GB
200 MB/s+32–64 GB

Configuration for Production

ini
# /etc/mysql/mysql.conf.d/innodb.cnf

[mysqld]
# Redo log (MySQL 8.0.30+)
innodb_redo_log_capacity  = 8589934592   # 8GB

# Buffer pool (typically 70-80% of RAM)
innodb_buffer_pool_size   = 48G
innodb_buffer_pool_instances = 8         # 1 per GB of buffer pool

# Checkpoint tuning
innodb_max_dirty_pages_pct      = 75     # default 90; flush earlier
innodb_max_dirty_pages_pct_lwm  = 65     # start flushing at 65%
innodb_io_capacity              = 2000   # IOPS available for background I/O
innodb_io_capacity_max          = 4000   # max IOPS during flush urgency

# Flush method (best for NVMe SSD)
innodb_flush_method = O_DIRECT

Monitoring Redo Log Health

sql
-- Checkpoint age as % of redo log capacity
-- Should stay below 75% during normal operations
SELECT
    variable_value AS checkpoint_age_bytes,
    ROUND(variable_value / @@innodb_redo_log_capacity * 100, 1) AS checkpoint_pct
FROM performance_schema.global_status
WHERE variable_name = 'Innodb_checkpoint_age';

-- If checkpoint_pct is consistently above 80%, increase redo log capacity

-- Track buffer pool hit rate
SELECT
    innodb_buffer_pool_read_requests,
    innodb_buffer_pool_reads,
    ROUND((1 - innodb_buffer_pool_reads / NULLIF(innodb_buffer_pool_read_requests, 0)) * 100, 2)
    AS hit_rate_pct
FROM (
    SELECT
        SUM(IF(variable_name = 'Innodb_buffer_pool_read_requests', variable_value, 0)) AS innodb_buffer_pool_read_requests,
        SUM(IF(variable_name = 'Innodb_buffer_pool_reads', variable_value, 0)) AS innodb_buffer_pool_reads
    FROM performance_schema.global_status
    WHERE variable_name IN ('Innodb_buffer_pool_read_requests', 'Innodb_buffer_pool_reads')
) x;
Warning

Changing innodb_redo_log_capacity on a running MySQL 8.0.30+ server takes effect immediately without restart. On older MySQL versions, changing innodb_log_file_size requires a clean server shutdown and can take significant time for large redo logs during recovery.

Key Takeaways
  • The InnoDB redo log default (100MB) is dangerously undersized for production — size it to 60–90 minutes of peak write throughput.
  • MySQL 8.0.30+ allows live redo log resizing via innodb_redo_log_capacity without a server restart.
  • Monitor checkpoint age as a percentage of redo log capacity — sustained above 75% means your redo log is too small.
  • Pair redo log tuning with innodb_io_capacity and innodb_max_dirty_pages_pct to control flush behavior under load.

Working with JusDB on MySQL Performance

JusDB tunes InnoDB configuration for MySQL deployments under heavy write loads — redo log sizing, buffer pool configuration, flush parameters, and storage I/O optimization. Our DBAs identify redo log pressure before it causes write stalls during peak traffic.

Explore JusDB MySQL Management →  |  Talk to a DBA

Related reading:

Share this article

JusDB Team

Official JusDB content team