RocksDB write_buffer_size and max_write_buffer_number tuning under a fixed memory budget
0 reputation · 24 May 2023, 17:31 UTC
0 reputation · 24 May 2023, 17:31 UTC
RocksDB's documented defaults set write_buffer_size to 64 MiB per column family and max_write_buffer_number to 2. That is adequate for light local workloads, but under sustained production write traffic the memtable fills quickly, flushes queue up, and the write path stalls once the buffer count limit is reached.
The unresolved decision is how much memory to dedicate to memtables without exceeding the process budget. Total memtable memory scales roughly as write_buffer_size × max_write_buffer_number per column family, so an instance with many column families multiplies the footprint quickly. A larger buffer reduces flush frequency and write amplification, but an oversized setting risks OOM. It is unclear whether per-column-family tuning or a shared WriteBufferManager with db_write_buffer_size is the safer way to enforce a global memory cap.
Given a fixed RAM budget and a target write throughput, what sizing rule should guide write_buffer_size and max_write_buffer_number? When many column families share one instance, is a WriteBufferManager-based cap preferable to per-column-family buffer limits for avoiding write stalls?
32275 reputation · 24 May 2023, 18:34 UTC
Under a fixed RAM budget, allocate a target fraction of the process memory to memtables, then derive write_buffer_size and max_write_buffer_number from that budget and the number of column families. When many column families share a DB instance, a shared WriteBufferManager with db_write_buffer_size is usually safer because it enforces a global cap and prevents the per‑CF multiplication that can exceed the budget.
write_buffer_size × max_write_buffer_number × column_family_count when each column family uses its own buffers.WriteBufferManager is enabled, the memtable footprint equals db_write_buffer_size regardless of column family count.write_buffer_size = 64 MiB, max_write_buffer_number = 2 per column family.Increasing write_buffer_size lets each memtable grow larger before a flush, which reduces flush frequency and write amplification but raises the peak memory that may be resident simultaneously. Raising max_write_buffer_number allows more memtables to stay alive before a forced flush, smoothing bursty writes but also increasing the worst‑case memtable footprint. The stall you observed occurs when the limit on the number of live memtables is reached while new writes keep arriving.
memtable_budget = f × total_RAM.max_write_buffer_number that matches your write‑burst tolerance (2 for steady load, 3–4 for bursty workloads).write_buffer_size = memtable_budget / (max_write_buffer_number × N).If N is large or variable, the per‑CF calculation can lead to very small buffers or, conversely, to an OOM risk if the product write_buffer_size × max_write_buffer_number × N exceeds the budget. In that case enable a WriteBufferManager and set db_write_buffer_size to the memtable budget from step 2. This caps total memtable memory globally, letting each column family draw from the shared pool as needed.
Could you confirm the exact number of column families (or an upper bound) so the per‑CF buffer size can be calculated?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.