Skip to content

feat(hotblocks): expose CF_TABLES memtable size and count - #106

Merged
mo4islona merged 1 commit into
masterfrom
feat/rocksdb-memtable-tuning
Jul 27, 2026
Merged

feat(hotblocks): expose CF_TABLES memtable size and count#106
mo4islona merged 1 commit into
masterfrom
feat/rocksdb-memtable-tuning

Conversation

@mo4islona

@mo4islona mo4islona commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Adds --rocksdb-write-buffer-mb and --rocksdb-max-write-buffers. Defaults are RocksDB's own (64 MB × 2), so this is inert until a deployment sets them.

Why

Production sets no memtable option at all.

The write stalls are the memtable ceiling, not compaction debt. Over 7 d, write_stopped fired on exactly two stacks, and the discriminator is exact:

signal stalled pods healthy pods
immutable_memtables max 2 1
files_at_level0 max 15 7–11
pending_compaction_bytes max 16.2 GB 2.3–6.0 GB

max_write_buffer_number is 2, so immutable_memtables == 2 is the stop condition, and it partitions the pods perfectly. L0 peaks at 15 against a stop trigger of 36; pending compaction peaks at 5.9 % of its hard limit. mainnet-internal-db-1 spends 1.2 % of wall time write-stopped (~2 h/week).

A 64 MB buffer is also most of the device write bill. Bench sweep at production I/O parity (Zstd WAL, 8 background jobs, direct I/O), free-run 45 × 2000:

write_buffer × buffers device writes write_stopped
64 MB × 2 — as deployed 39.07 GB 5.97 %
128 MB × 4 38.26 GB 0.00 %
256 MB × 4 23.45 GB 0.00 %
512 MB × 2 16.29 GB 0.00 %
512 MB × 4 16.28 GB 0.00 %
1024 MB × 4 11.98 GB 0.00 %

Two effects separate cleanly: count fixes the stall (128 × 4 is already at zero with writes unchanged) and size drives volume (512 × 2 and 512 × 4 are identical). Commit max at 512 × 4 is 118 ms against 1569 ms as deployed; throughput rises 39 %.

Recommended deployment value

--rocksdb-write-buffer-mb 512 --rocksdb-max-write-buffers 4 — 2 GB of memtable, scoped to CF_TABLES.

Before rollout

  • Boot time must be measured on internal first. A larger memtable means a longer WAL replay, and this service has a documented startup-probe kill-loop at a 90 s budget.
  • max_bytes_for_level_base is untouched at 256 MB, now smaller than one memtable — the numbers above are a floor on what tuning can do, not a ceiling.
  • Bench live is ~130 MB vs production's ~62 GB. The stall mechanism is scale-free; the volume ratios are not guaranteed to hold.

Full record: docs/measurements/2026-07-27-rocksdb-memtable-tuning.md.

Bearing on ADR 0002

Same bench, same build, same session: mdbx writes 13.27 GB free-run / 3.28 GB paced, against the tuned reference's 16.28 / 4.69 GB — a 1.2–1.4× gap where the ADR gates the port on ≥ 3×. At 1024 MB × 4 RocksDB writes less than mdbx. The engine case now rests on commit tails (mdbx p99 379 µs vs 3743 µs) and per-dataset isolation, not on write amplification.

🤖 Generated with Claude Code

Production runs the stock 64 MB x 2 memtable, and both costs that motivated
ADR 0002 trace back to it. The write stalls are the ceiling being hit --
immutable_memtables peaks at exactly 2 on every stalled pod and 1 on every
healthy one, while files_at_level0 stays at 15 against a stop trigger of 36
and pending_compaction_bytes at 5.9% of its limit. And a 64 MB buffer flushes
small L0 files continuously, which is most of the device write bill: at
production I/O parity the bench goes 39.1 -> 16.3 GB at 512 MB, with the
curve still falling at 1024.

Defaults keep RocksDB's own values so the flags are inert until a deployment
sets them. Scoped to CF_TABLES, which takes essentially all the write volume,
so the memory cost is paid once rather than per column family.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mo4islona
mo4islona merged commit 5e679ae into master Jul 27, 2026
3 checks passed
@mo4islona
mo4islona deleted the feat/rocksdb-memtable-tuning branch July 27, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant