RocksDB Write Stalls From Level-0 SST Buildup: A Diagnostic Guide
Write stalls in RocksDB often mean Level 0 SST files have grown past the stop-writes trigger. This guide shows how to recognize the condition, check L0 count versus triggers, verify compaction resources, and apply targeted fixes without manual file deletion.
22 May 2026, 06:52 UTC

The problem you are seeing
Writes suddenly block or spike in latency while reads remain responsive. RocksDB LOG shows stall and slowdown notices tied to level-0 SST file count. The useful takeaway is that this is a backpressure mechanism, not a crash. RocksDB stops accepting new writes when Level 0, the first on-disk level that receives flushed memtables, grows beyond a configured threshold. The stall clears only after compaction drains L0.
SST stands for Sorted String Table, an immutable on-disk file. Level 0 files can overlap in key range, so reads must check many files. To protect read amplification and compaction stability, RocksDB slows and then stops writes when L0 grows too fast.
Recognizable condition
- Abrupt write latency increase or write calls that block, while read latency stays near normal.
- Log lines mentioning stall, slowdown, or writes stopped because of too many L0 files.
- NUM_FILES_AT_LEVEL0 rises steadily during a write burst and stays high after the burst ends.
Cause and diagnostic table
| Observed pattern | Likely cause | Why it matters |
|---|---|---|
| L0 count climbs during burst writes, then compaction lags | Write burst outpaces memtable flush to L0 | Flush creates new L0 files faster than compaction can merge them |
| L0 count high, compaction pending bytes growing | Too few background compaction threads | max_background_compactions or max_subcompactions is zero or too low for load |
| L0 count high, disk utilization near 100%, WAL sync latency high | Slow storage I/O | Compaction reads and writes cannot keep up, backlog accumulates |
| L0 count grows without bound, no compaction activity | Auto-compactions disabled or paused | Compaction is off, so L0 is never drained |
Default trigger values for level0_slowdown_writes_trigger and level0_stop_writes_trigger differ across RocksDB releases. Read them from the running instance, do not assume 20 and 36.
Ordered checks
1. Confirm stall signal in logs and current L0 metrics
Run on the host that holds the RocksDB log directory, with read permission for the log files and access to the DB instance for metrics.
# tail -n 200 /var/lib/rocksdb/db/LOGLook for stall/slowdown messages referencing level-0 file count.
Query DB properties from an admin client or monitoring exporter that can call DB::GetProperty. Use placeholders for the DB path and property names.
DB::GetProperty(db, "rocksdb.num-files-at-level0")
DB::GetProperty(db, "rocksdb.level0-slowdown-writes-trigger")
DB::GetProperty(db, "rocksdb.level0-stop-writes-trigger")
DB::GetProperty(db, "rocksdb.cur-size-all-mem-tables")
DB::GetProperty(db, "rocksdb.num-running-compactions")Risk: querying properties is read-only. Ensure the tool connects to the correct instance to avoid mixing metrics.
2. Compare L0 count to triggers
Compare rocksdb.num-files-at-level0 to the two triggers from the same dump. If the count is at or above level0_stop_writes_trigger, writes are blocked. If between slowdown and stop, writes are throttled.
Also check pending compaction bytes via dbstats if available. Growing pending bytes with a flat running compaction count points to thread starvation.
3. Verify compaction resources and storage health
Check configured background work limits. These are set at open time and can be read via DB properties or config export.
DB::GetProperty(db, "rocksdb.max-background-compactions")
DB::GetProperty(db, "rocksdb.max-subcompactions")Confirm compaction is not paused via the DB options.
Check disk utilization and WAL sync latency on the volume that holds SST and WAL. High iowait or sync latency explains why compaction cannot drain L0 even with threads available.
Fixes tied to findings
If L0 exceeds stop trigger due to burst
Temporary relief: raise level0_stop_writes_trigger for the running instance if your deployment supports dynamic option changes, and add background compaction threads. This is a temporary mitigation, not a fix.
SetOption(db, "level0-stop-writes-trigger", "50")
SetOption(db, "max-background-compactions", "4")Force a memtable flush to move data out of memory and allow compaction to start on a stable set of files.
Flush(db, column_family)Risk: raising the stop threshold hides I/O saturation and increases read amplification from many overlapping L0 files. Revert the temporary increase after L0 drains.
If compaction is thread-starved
Increase max_background_compactions and max_subcompactions to match CPU and disk capability, then validate under production-like load. Increasing threads consumes more CPU and disk bandwidth.
For sustained load, tune target_file_size_base and compaction readahead so compactions produce appropriately sized files and reduce number of L0 files created per flush.
If storage is saturated
Reduce write throughput until compaction drains L0. If possible, migrate SST and WAL to faster devices. Increase bytes_per_sync to reduce fsync frequency at the cost of durability window, only after reviewing durability requirements.
Never manually delete SST or manifest files. Use RocksDB APIs and official tools only.
Escalation criteria
- Writes remain blocked after L0 count falls below level0_stop_writes_trigger for several minutes.
- SST checksum errors, manifest corruption, or repeated compaction failures appear in logs alongside the stall.
- Compaction backlog grows despite increased threads and available I/O, indicating possible data distribution anomaly or bug.
Escalate to storage and RocksDB engineering with log excerpts, property dumps before and after the incident, and disk metrics.
Limitations and practical verification
Raising thresholds can mask underlying I/O saturation. Increasing background compaction threads can worsen latency for reads if disk is already saturated.
Verify recovery by dumping dbproperties on the running instance and confirming rocksdb.num-files-at-level0 falls below rocksdb.level0-stop-writes-trigger in the same output. Tail rocksdb.log during a controlled write burst and correlate stall log lines with rising L0 counts, then confirm writes unblock once compaction drains L0.
A safe isolation test is to disable auto-compactions in a non-production clone, run bulk puts, observe the stall, then re-enable compaction and measure recovery latency. Do not run this test on production data.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.