# InnoDB Page Flushing

InnoDB uses a single `buf_flush_page_cleaner` thread to flush dirty pages—modified pages that have not yet been written to data files—from the [InnoDB buffer pool](https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-buffer-pool) to disk. This thread handles page flushing regardless of the number of buffer pool instances. These dirty pages are flushed using a least-recently used (LRU) algorithm, which manages memory efficiently by prioritizing the eviction of older, less frequently accessed pages.

### innodb\_max\_dirty\_pages\_pct

The [innodb\_max\_dirty\_pages\_pct](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_max_dirty_pages_pct) variable specifies the target maximum percentage of unwritten (dirty) pages in the [buffer pool](https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-buffer-pool). If this percentage is exceeded, flushing will take place.

### innodb\_max\_dirty\_pages\_pct\_lwm

The [innodb\_max\_dirty\_pages\_pct\_lwm](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_max_dirty_pages_pct_lwm) variable determines the low-water mark percentage of dirty pages that will enable preflushing to lower the dirty page ratio. The default value is `0`.

{% hint style="success" %}
To make flushing more eager and ensure more consistent background I/O, you can set `innodb_max_dirty_pages_pct_lwm` to a very low value, such as `0.001`:

`SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.001;`
{% endhint %}

## Configuring the InnoDB I/O Capacity

increasing the amount of I/O capacity available to InnoDB can help increase the performance of page flushing. The unit of [innodb\_io\_capacity](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_io_capacity) is the number of data pages (of the size [defined by](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_page_size) `innodb_page_size`) that can be written per second.

### Scope of Throttling

It is critical to understand the restricted scope of this variable in modern versions of MariaDB:

* Checkpoint Flushing Only: [innodb\_io\_capacity](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_io_capacity) only throttles checkpoint flushing (background or idle flushing). It does not throttle LRU eviction flushing, which handles the removal of pages when the buffer pool is at capacity.
* Interaction with `innodb_flush_sync`: The `innodb_io_capacity` limit is only effective when [innodb\_flush\_sync](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_flush_sync) is set to `OFF`. When `innodb_flush_sync=ON` (the default), InnoDB may ignore this limit during aggressive "furious flushing" if a log checkpoint is urgently required to prevent the redo log from filling up.
* No Throttling for Buffer Pool Loading: As of MariaDB [10.5.19](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/changelogs/changelogs-mariadb-105-series/mariadb-10-5-19-changelog), [10.6.12](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/changelogs/10.6/10.6.12), [10.11.2](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/changelogs/10.11/10.11.2), and later, this parameter no longer throttles the loading of buffer pool dumps at startup ([MDEV-25417](https://jira.mariadb.org/browse/MDEV-25417)). Startup loads are now performed at best-effort speed.
* Interaction with [innodb\_flush\_sync](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_flush_sync): The `innodb_io_capacity` limit is only effective when [innodb\_flush\_sync](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_flush_sync) is set to `OFF`. When `innodb_flush_sync=ON` (the default), InnoDB may ignore this limit during aggressive "furious flushing" if a log checkpoint is urgently required to prevent the redo log from filling up.
* Shared Storage Consideration: If the InnoDB redo log resides on the same physical storage as the data files, ensure you leave some spare capacity for log writes so they are not blocked by background page flushing.

### Adjusting I/O Capacity

The amount of I/O capacity available to InnoDB can be configured by setting the [innodb\_io\_capacity](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_io_capacity) system variable. This system variable can be changed dynamically with [SET GLOBAL](https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/set-commands/set#global-session):

```sql
SET GLOBAL innodb_io_capacity=20000;
```

The maximum amount of I/O capacity available to InnoDB in an emergency defaults to either `2000` or twice `innodb_io_capacity`, whichever is higher, or can be directly configured by setting the [innodb\_io\_capacity\_max](https://www.google.com/search?q=innodb-system-variables.md%23innodb_io_capacity_max) system variable.

#### Device-Specific Recommendations

When setting these variables, consider the physical limits of your storage hardware:

| Storage Device Type | Typical IOPS Capability | Recommended innodb\_io\_capacity |
| ------------------- | ----------------------- | -------------------------------- |
| SATA HDD            | \~100 – 200             | 100 – 200                        |
| SATA SSD            | \~50,000 – 100,000      | 2,000 – 20,000                   |
| NVMe SSD            | 500,000+                | 20,000 – 80,000+                 |

For high-speed NVMe storage, a sensible value for `innodb_io_capacity` may be as high as 80,000.

### Page Flushing Before MariaDB Server 10.5

InnoDB supported multiple partitions and threads to reduce internal mutex contention. These features were rendered unnecessary by architectural improvements—such as splitting the buffer pool mutex and implementing read-write locks for the page hash—and were removed to reduce context-switching overhead:

* [innodb\_page\_cleaners](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_page_cleaners): Previously allowed the use of multiple cleaner threads; it was deprecated and ignored in [MariaDB 10.5.1](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/changelogs/changelogs-mariadb-105-series/mariadb-1051-changelog) and removed entirely in [MariaDB 10.6](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/10.6/what-is-mariadb-106).
* [innodb\_buffer\_pool\_instances](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_buffer_pool_instances): Partitioned the buffer pool into multiple instances; this was removed in MariaDB [10.5](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/old-releases/10.5/what-is-mariadb-105) as the buffer pool now runs as a single instance.
* [innodb\_mtflush\_threads](https://mariadb.com/docs/server/server-usage/storage-engines/innodb-system-variables#innodb_mtflush_threads): A [Fusion-io](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/changelogs/changelogs-mariadb-100-series/mariadb-10015-fusion-io-changelog) specific parameter for multi-threaded flushing, removed in [MariaDB 10.3.2](https://app.gitbook.com/s/aEnK0ZXmUbJzqQrTjFyb/community-server/old-releases/10.3/10.3.2).

## See Also

* [Significant performance boost with new MariaDB page compression on FusionIO](https://blog.mariadb.org/significant-performance-boost-with-new-mariadb-page-compression-on-fusionio/)
* [InnoDB Redo Log](https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-redo-log)
* [InnoDB Buffer Pool](https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-buffer-pool)
* [InnoDB Background Thread Pool](https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-architecture-for-mariadb-enterprise-server/mariadb-enterprise-server-innodb-background-thread-pool)

<sub>*This page is licensed: CC BY-SA / Gnu FDL*</sub>

{% @marketo/form formId="4316" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-page-flushing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
