> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paradedb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Write Throughput

> Settings to improve write performance

These actions can improve the throughput of `INSERT`/`UPDATE`/`COPY` statements to the BM25 index.

## Ensure Merging Happens in the Background

During every `INSERT`/`UPDATE`/`COPY`/`VACUUM`, the BM25 index runs a compaction process that looks for opportunities to merge segments
together. The goal is to consolidate smaller segments into larger ones, reducing the total number of segments and improving query performance.

Segments become candidates for merging if their combined size meets or exceeds one of several **configurable layer thresholds**. These thresholds define target
segment sizes — such as `10KB`, `100KB`, `1MB`, etc. For each layer, the compactor checks if there are enough smaller segments whose total size adds up to the threshold.

The default layer sizes are `100KB`, `1MB`, `100MB`, `1GB`, and `10GB` but can be configured.

```sql theme={null}
ALTER INDEX search_idx SET (background_layer_sizes = '100MB, 1GB');
```

By default, merging happens in the background so that writes are not blocked. The `layer_sizes` option allows merging to happen in the foreground.
This is not typically recommended because it slows down writes, but can be used to apply back pressure to writes if segments are being created faster
than they can be merged down.

```sql theme={null}
ALTER INDEX search_idx SET (layer_sizes = '100KB, 1MB');
```

Setting `layer_sizes` to `0` disables foreground merging, and setting `background_layer_sizes` to `0` disables background merging.

## Increase Work Memory for Bulk Updates

`work_mem` controls how much memory to allocate to a single `INSERT`/`UPDATE`/`COPY` statement. Each statement that writes to a BM25 index is required to have at least `15MB` memory. If
`work_mem` is below `15MB`, it will be ignored and `15MB` will be used.

A good starting point for `work_mem` is `(RAM - shared_buffers) / (3 * max_connections)`. If your typical update patterns are large, bulk updates (not single-row updates) a larger value may be better.

```sql theme={null}
SET work_mem = 64MB;
```

Since many write operations can be running concurrently, this value should be raised more conservatively than `maintenance_work_mem`.

## Increase Mutable Segment Size

The `mutable_segment_rows` setting enables use of mutable segments, which buffer new rows in order to amortize the cost of indexing them.
By default, it is set to `1000`, which means that 1000 writes are buffered before being flushed.

```sql theme={null}
ALTER INDEX search_idx SET (mutable_segment_rows = 1000);
```

A higher value generally improves write throughput at the expense of read performance,
since the mutable data structure is slower to search. Additionally, the mutable data structure is read into
memory, so higher values cause reads to consume more RAM.

Alternatively, this setting can be set to apply to all indexes in the database:

```sql theme={null}
SET paradedb.global_mutable_segment_rows = 1000
```

If both a per-index setting and global setting exist, the global `paradedb.global_mutable_segment_rows` will be used.
To ignore the global setting, set `paradedb.global_mutable_segment_rows` to `-1` (this is the default).

```sql theme={null}
SET paradedb.global_mutable_segment_rows = -1
```
