Page Cleaner Threads in MariaDB control how InnoDB writes modified pages from the buffer pool to disk, thereby smoothing out response times under write load. Understanding the current architecture—which uses a single cleaner thread—helps avoid bottlenecks in the write path and maintains the database Consistent performance.
Key points
- Architecture: A cleaner thread flushes dirty pages regardless of buffer pool instances.
- Versions: The variable
innodb_page_cleanersDeprecated as of MariaDB 10.6. - LRU Focus: Flush selection is based on LRU expiration and checkpoint progress.
- Myth: More threads do not automatically mean better performance.
- Practice: The size of the buffer pool, I/O capacity, and checkpointing are the main factors influencing the result.
What exactly the Page Cleaner does
The Page Cleaner thread says Dirty It retrieves pages from the InnoDB buffer pool before user operations are written directly to disk. This decouples write operations from queries and noticeably reduces the variance in response times, especially during peak loads. I see the Cleaner as a pacemaker: It breaks writes down into manageable chunks instead of processing large waves uncontrollably. The thread retrieves pages that end up at the end of the LRU list, ensuring the cache quickly becomes available again for hot data. At the same time, it drives the checkpoint process forward so that not too many unwritten changes remain stuck in memory. Anyone who understands this process can more quickly determine whether I/O is the bottleneck, or whether the bottleneck is more likely due to an insufficient cache size and too many dirty pages.
Version Status: From Many Threads to One
Historically, it was possible to configure multiple cleaners, but MariaDB 10.5.1 initiated the redesign, and MariaDB 10.6 removed innodb_page_cleaners once and for all. Since then, a single buf_flush_page_cleaner-A single thread handles the work for all buffer pool instances. This reduces coordination overhead, simplifies tuning, and reflects the understanding that a good algorithm is more important than having multiple threads. Anyone following instructions from MySQL or older articles will quickly run into parameters that are now ineffective. I first check the exact MariaDB version before adjusting any supposed tuning parameters. This way, I avoid wasting time and focus on the tuning parameters that actually affect the Write Path really influence.
Buffer Pool, Dirty Pages, and LRU
The buffer pool keeps hot data in RAM and saves on expensive Disc-accesses. As soon as transactions write data, dirty pages are created, which initially exist only in memory. The cleaner flushes them out in a timely manner so that the LRU is eventually freed up and frequently read pages remain at the top of the cache. I keep an eye on how many buffer pool instances are active and how access is distributed, because concurrency can alleviate queues. If you want to dive deeper, you’ll find practical tips on Buffer Pool Instances, for example, for multicore hosts. Ultimately, the dirty-page ratio shows whether the flush rate keeps pace with the write rate and whether the cache is Hits supplies.
Checkpoint Progress and Latency
The checkpoint sets a marker indicating the point up to which changes are safely stored on disk, and the page cleaner moves this marker forward. If the checkpoint falls behind, log utilization and write amplification increase, which is reflected in commit time and peak n during queries. I regularly check how much the checkpoint distance fluctuates and whether the Cleaner is causing excessive spikes. If smoothing fails, peak periods may occur during which user threads become blocked. For a basic understanding, it helps to take a look at Checkpointing and Write Amplification in the context of web hosting. Anyone who reviews these metrics can quickly determine whether Flush-whether the work is completed on time or whether the system has to scramble to catch up in later phases.
Common Misconceptions About Tuning
Many people expect that additional background threads will automatically result in higher throughput, but that is not the case here. The key factors remain the quality of the flush algorithm and the right amount of I/O-Work per interval. A cleaner that’s too aggressive causes short load spikes that drive up response times. A cleaner that’s too conservative accumulates too many dirty pages, leading to larger flush waves later on. Both result in a seesaw effect on latencies. I therefore aim for a consistent pattern that matches the memory subsystem and minimizes the impact on user threads as much as possible. blocked.
Metrics and Monitoring: What I Check
When making decisions, I rely on numbers, not gut feelings. I monitor the dirty page percentage, checkpoint progress, write and fsync rates, as well as wait times on redo logs and data files. If commit times fluctuate under load, I take a look at flush backlogs and the size of the redo log files. The percentage of pages at the end of the LRU list also indicates eviction pressure and the need for flush operations. Outliers in IOPS indicate that the cleaner is writing packets that are too large or that the storage limit has been reached. These metrics reveal whether the bottleneck is more likely due to cache size, Memory-Throughput or flush strategy.
Configuration: Choosing the Right Sizes and I/O Capacity
The most important tuning parameters remain buffer pool size, I/O capacity, and log layout. A larger buffer pool reduces read pressure, but must not allow the dirty page ratio to grow unchecked. The I/O capacity parameters control how much the cleaner attempts to write per unit of time. Values that are too small lead to bottlenecks, while values that are too large cause spikes in the latency profile. I adjust these values to match the actual storage system rather than relying on abstract default values. The following table summarizes relevant settings that affect the behavior of the Flush-shape the process.
| Setting/Aspect | Effect on Page Cleaner | Note for MariaDB | Practical Guidance |
|---|---|---|---|
innodb_buffer_pool_size | Affects the amount of dirty pages and eviction pressure | A larger pool requires a consistent flush cadence | Use RAM, but leave some free for the OS and Query-Keep the cache |
innodb_io_capacity / innodb_io_capacity_max | Limited Scope of Planned Flushing Work | Adjust to actual SSD/NVMe IOPS | Start with a conservative value, then increase it gradually |
innodb_flush_log_at_trx_commit | Controls the Commit-Fsync frequency | Choice Affects Latency and Shelf Life | „1“ for the longest shelf life; „2/0“ for a shorter shelf life Latency |
| Redo Log Size | Effective against checkpoint distance and flush waves | Too small forces frequent checkpoints | Use a larger size to smooth out write spikes |
innodb_page_cleaners (old) | No influence today | Removed starting with MariaDB 10.6 | Don't touch it anymore; focus on active Parameters |
Practical Guide: Step-by-Step Testing
I start with a clear baseline under load before changing any settings. Then I adjust innodb_io_capacity I proceed in small steps and monitor whether latency spikes occur less frequently. If longer flush waves appear, I increase the redo log size to give the checkpoint more buffer space. Next, I check whether the buffer pool has enough space so that hot data isn’t evicted too quickly. I allow sufficient time for each change so that its effects and side effects become clearly apparent. Only when both metrics and the user experience improve together do I check off the Step from.
Effect of the Doublewrite Buffer
The double-write buffer protects pages from partial writes and corrupted blocks, but it also affects the write rate and flush patterns. Especially when there is a high proportion of updates, it can influence the perceived throughput of the cleaner. Modern storage systems with persistent write ordering mitigate some of these issues, but the effect remains measurable. I therefore evaluate the workload, data integrity expectations, and acceptable latency before adjusting this setting. If you need more details, you can find background information in the article on Double-write buffer. This makes it possible to determine whether the service life and Protection Priority over minimal latency.
Common Symptoms and Remedies
If commit times spike even though the CPU is idle, this indicates a flush backlog or poor storage performance. Significant fluctuations in IOPS suggest that flush packets are too large; in that case, I reduce the I/O capacity and increase the size of the redo log. If the dirty page percentage remains consistently high, either the cleaner is operating too conservatively or the buffer pool is too small. If frequently used pages quickly slide to the end of the LRU list, there is a lack of cache space, or the write load is putting too much pressure on the pool. In hosting environments, shared storage often slows things down; the only solution here is to monitor load throughout the day and, if necessary, switch to faster storage media. I document every change so that the cause and Effect remain clear later on.
How the Cleaner Prioritizes Between the Flush List and LRU
When writing, InnoDB distinguishes between two main sources: the LRU list (pages that must make room for new accesses) and the flush list (all dirty pages, sorted by oldest log sequence number). The Page Cleaner balances these two goals: It cleans up at the end of the LRU list to avoid evictions, and simultaneously pulls from the flush list to keep the checkpoint moving forward at a constant pace. If free buffer space comes under pressure, LRU-flush takes priority; conversely, if the checkpoint distance grows, the Cleaner increases the proportion taken from the Flush List. This switching behavior explains why latency profiles change with varying workloads: As read pressure increases, LRU flushes dominate; as write pressure increases, checkpoint work dominates. I analyze the pattern in the monitoring data to decide whether I need to optimize I/O capacity or the redo log reserve.
Adaptive Flushing: Interpreting Thresholds Correctly
MariaDB uses adaptive flushing to dynamically adjust the write rate based on redo consumption and the dirty page ratio. In practice, I monitor three metrics: the target value for dirty pages, the low-water mark, and the current write rate. If the dirty page ratio exceeds the target, the cleaner tightens the reins; if it falls below it, the cleaner becomes more restrained. A low-water mark that is set too low causes frequent flushes and can generate short but noticeable latency spikes. A threshold that’s too high allows too much “dirt” to remain in memory, which later produces larger spikes. I adjust the thresholds to match the characteristics of the storage system: fast NVMe SSDs can handle continuous, moderately higher flush rates; slower systems benefit from smoother, smaller batches.
Using Storage-Specific Options Wisely
The Page Cleaner doesn't operate in a vacuum—the choice of flush method and the behavior of the file system determine the result. With innodb_flush_method I control whether InnoDB writes pages directly (O_DIRECT) or through the OS cache. Direct writing avoids double caching and stabilizes latencies on Linux with XFS/EXT4. However, file systems like ZFS handle O_DIRECT differently; in those cases, I check whether a synchronized method (fsync/O_DSYNC) provides the more consistent profile. It's also worth taking a look at neighborhood flushing (flush neighbors): On HDD arrays, writing adjacent blocks simultaneously can be beneficial; on SSD/NVMe, I limit this to avoid unnecessary write amplification. The key is to ensure that the configuration matches the physical medium—even the best cleaner algorithm is of little use if the underlying storage is being slowed down.
Monitoring in Practice: Queries That Help Me
To get a quick overview, I use three perspectives: global status values, InnoDB metrics, and the periodic dump.
- Quick Facts:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty%';,... LIKE 'Innodb_os_log_written';,... LIKE 'Innodb_log_waits';. Climb log waits, the redo log is too small or the flush operation is too slow. - Level of detail:
SHOW ENGINE INNODB STATUS\Gprovides checkpoint positions (LSN), flush list lengths, and indications of bottlenecks. I compare the „log sequence number“ and „last checkpoint at“ to estimate the checkpoint distance. - More Detailed Telemetry:
SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_%dirty%';or... LIKE 'log_%';highlights trends that are easily overlooked in brief tests.
The key is the correlation: If commit latencies spike at the same time as the Fsync rate increases, the cleaner is likely set too aggressively. If the dirty page ratio and checkpoint distance increase together, either the flush throughput is insufficient or the redo log is too small.
Workload Profiles: OLTP, Reporting, Bulk
Depending on the workload, I adjust my approach. In OLTP environments, I aim for consistent, small flush batches and a narrow latency window—here, moderately configured innodb_io_capacity and sufficient redo buffers are crucial. For reporting or ETL windows, I occasionally allow for higher flush rates, but I make sure they don’t extend into peak user periods. For bulk data loads, I prefer larger redo logs and—if durability requirements allow—a temporarily relaxed Fsync policy (innodb_flush_log_at_trx_commit=2). The Page Cleaner can then continuously „catch up“ without slowing down user transactions. Once it's finished, I restore the stricter settings so that day-to-day operations remain stable.
Long-term effects, Purge, and indirect effects
Even though the purge thread serves a different purpose (cleaning up old versions), its speed affects the overall picture. If old versions remain for a long time, the space requirements grow, and the memory and I/O loads are distributed less efficiently. This can indirectly strain the page cleaner because more pages are tied up in the pool and the LRU comes under pressure more quickly. I therefore keep an eye on purge delays and ensure that no long-running transactions „lock up“ the system. Steady purge progress, a continuously active cleaner, and a balanced write cadence—these three gears must mesh seamlessly.
Troubleshooting Checklist for the Write Path
- Checkpoint distance high and rising? Increase the redo log size and
innodb_io_capacityRaise it, then check the alignment again. - IOPS spikes and commit spikes?
innodb_io_capacitySlightly reduce, smooth the batch size, take the double-write effect into account. - Is the dirty page ratio consistently high? Increase the buffer pool size or tighten adaptive flushing; check the workload for hotsets.
- Are log waits visible? Either the redo buffer is too small or the flush is lagging. First increase the redo buffer size, then fine-tune the cleaner throughput.
- LSN progress erratic? Flush packets are inconsistent. Gradually adjust the values until steady progress becomes apparent.
- Storage-related bottlenecks? Validate the flush method, scheduler, and RAID/SAN cache settings; use sustained IOPS rather than peak IOPS as the target metric.
Example: Calibration in Three Rounds
In a write-intensive OLTP instance, I start by measuring the load during the production window. Round 1: I measure the redo log fill levels and the checkpoint distance. The log is often 70–80 % full, and the distance fluctuates widely—so I double the redo size. Round 2: After retesting, the latencies even out, but Fsync spikes occasionally occur. I reduce innodb_io_capacity Moderate, until the IOPS distribution evens out. Round 3: The dirty page ratio remains near the upper limit. I allocate more RAM to the buffer pool, which takes some of the load off the LRU and makes the cleaner’s work more predictable. Result: Commit-P95 drops noticeably, the IOPS curve becomes more even, and the checkpoint progresses steadily—exactly the pattern I’m aiming for.
Briefly summarized
A single cleaner thread manages the flushing of dirty pages, keeps the checkpoint moving, and protects queries from heavy write spikes. Relevant tuning parameters include buffer pool size, I/O capacity, redo log layout, and the characteristics of the storage system. Outdated tuning parameters such as innodb_page_cleaners I no longer pay attention to those and focus instead on metrics that have a direct impact. If you monitor metrics such as the dirty page rate, checkpoint interval, and commit duration, you’ll identify bottlenecks more quickly. Incremental changes with a clear baseline deliver reliable results without hiding side effects. This way, the Page Cleaner works quietly in the background, and the Response time remains consistent—even under load.


