Skip to content

Add RocksDB rate limiter I/O usage metrics#14884

Closed
xingbowang wants to merge 2 commits into
facebook:mainfrom
xingbowang:2026_06_24_main
Closed

Add RocksDB rate limiter I/O usage metrics#14884
xingbowang wants to merge 2 commits into
facebook:mainfrom
xingbowang:2026_06_24_main

Conversation

@xingbowang

@xingbowang xingbowang commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary:

Add rate limiter statistics that make it easier to diagnose whether RocksDB background IO is being throttled by the GenericRateLimiter.

New ticker counters:

  • rocksdb.rate.limiter.bytes.read/write: bytes granted by the limiter, split by operation type.
  • rocksdb.rate.limiter.requests.read/write: requests granted by the limiter, split by operation type.
  • rocksdb.rate.limiter.delayed.requests.read/write: requests that actually had to wait for a future refill because available tokens were exhausted.
  • rocksdb.rate.limiter.total.wait.micros.read/write: cumulative wait time for delayed requests.

New histograms:

  • rocksdb.rate.limiter.wait.micros.read/write: per-request wait latency for delayed requests, enabling percentile debugging.

GenericRateLimiter now overrides the OpType-aware Request() path so these stats preserve the configured limiter mode. The legacy three-argument Request() path is treated as write IO for compatibility. Existing NUMBER_RATE_LIMITER_DRAINS is left intact, but the new delayed request counters are the clearer signal for out-of-token throttling because one delayed request can observe multiple drain intervals.

Also update the Java ticker and histogram mappings so Java consumers can access the new statistics.

Test Plan:

  • make format-auto
  • make -j16 rate_limiter_test statistics_test
  • ./rate_limiter_test
  • ./statistics_test
  • make check-sources
Summary:
Add rate limiter statistics that make it easier to diagnose whether RocksDB background IO is being throttled by the GenericRateLimiter.

New ticker counters:
- rocksdb.rate.limiter.bytes.read/write: bytes granted by the limiter, split by operation type.
- rocksdb.rate.limiter.requests.read/write: requests granted by the limiter, split by operation type.
- rocksdb.rate.limiter.delayed.requests.read/write: requests that actually had to wait for a future refill because available tokens were exhausted.
- rocksdb.rate.limiter.total.wait.micros.read/write: cumulative wait time for delayed requests.

New histograms:
- rocksdb.rate.limiter.wait.micros.read/write: per-request wait latency for delayed requests, enabling percentile debugging.

GenericRateLimiter now overrides the OpType-aware Request() path so these stats preserve the configured limiter mode. The legacy three-argument Request() path is treated as write IO for compatibility. Existing NUMBER_RATE_LIMITER_DRAINS is left intact, but the new delayed request counters are the clearer signal for out-of-token throttling because one delayed request can observe multiple drain intervals.

Also update the Java ticker and histogram mappings so Java consumers can access the new statistics.

Test Plan:
- make format-auto
- make -j16 rate_limiter_test statistics_test
- ./rate_limiter_test
- ./statistics_test
- make check-sources
@meta-cla meta-cla Bot added the CLA Signed label Jun 25, 2026
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown

✅ clang-tidy: No findings on changed lines

Completed in 62.2s.

@meta-codesync

meta-codesync Bot commented Jun 25, 2026

Copy link
Copy Markdown

@xingbowang has imported this pull request. If you are a Meta employee, you can view this in D109694030.

@github-actions

Copy link
Copy Markdown

🟡 Codex Code Review

Auto-triggered after CI passed — reviewing commit fb90cde


Codex review failed before producing findings.

WARNING: proceeding, even though we could not create PATH aliases: Refusing to create helper binaries under temporary dir "/tmp" (codex_home: AbsolutePathBuf("/tmp/codex-home"))
error: the argument '--base <BRANCH>' cannot be used with '[PROMPT]'

Usage: codex exec review --commit <SHA> --base <BRANCH> --title <TITLE> --model <MODEL> --config <key=value> --dangerously-bypass-approvals-and-sandbox --output-last-message <FILE> [PROMPT]

For more information, try '--help'.

ℹ️ About this response

Generated by Codex CLI.
Review methodology: claude_md/code_review.md

Limitations:

  • Codex may miss context from files not in the diff
  • Large PRs may be truncated
  • Always apply human judgment to AI suggestions

Commands:

  • /codex-review [context] — Request a code review
  • /codex-query <question> — Ask about the PR or codebase
@meta-codesync

meta-codesync Bot commented Jun 25, 2026

Copy link
Copy Markdown

@xingbowang has imported this pull request. If you are a Meta employee, you can view this in D109694030.

@github-actions

Copy link
Copy Markdown

✅ Claude Code Review

Auto-triggered after CI passed — reviewing commit fb90cde


Summary

Well-structured PR that adds useful rate limiter I/O diagnostics with clean separation of concerns. The RequestImpl refactoring correctly narrows the mutex scope and records stats outside the lock. No correctness bugs found.

High-severity findings (0):

No high-severity findings.

Full review (click to expand)

Findings

🔴 HIGH

None.

🟡 MEDIUM

M1. Test does not cover read-path delayed requests or read histogram — util/rate_limiter_test.cc
  • Issue: The Statistics test exercises write-mode delayed requests thoroughly but never verifies RATE_LIMITER_DELAYED_REQUESTS_READ, RATE_LIMITER_TOTAL_WAIT_MICROS_READ, or the RATE_LIMITER_WAIT_MICROS_READ histogram. The second half uses kAllIo mode but only issues a single 10-byte read that fits in the bucket without waiting.
  • Root cause: The test was written with write-mode in mind; the read section verifies bytes/requests counting but not the delay path.
  • Suggested fix: Add a test case that uses kAllIo or kReadsOnly mode, exhausts the bucket with one read request, then issues a second read that must wait, and verifies RATE_LIMITER_DELAYED_REQUESTS_READ, RATE_LIMITER_TOTAL_WAIT_MICROS_READ > 0, and RATE_LIMITER_WAIT_MICROS_READ histogram count == 1.
M2. Test does not cover the legacy 3-arg Request() path — util/rate_limiter_test.cc
  • Issue: The PR documents that the 3-arg Request() treats all requests as kWrite for compatibility, but no test verifies this behavior. If the delegation were accidentally changed, there would be no regression protection.
  • Suggested fix: Add a test that calls the 3-arg Request(bytes, pri, stats) and verifies that RATE_LIMITER_BYTES_WRITE and RATE_LIMITER_REQUESTS_WRITE are incremented (not the read variants).

🟢 LOW / NIT

L1. Helper functions could use default case — util/rate_limiter.cc:19-66
  • Issue: The five helper functions use switch-on-enum without default, followed by assert(false); return. Adding default: would suppress potential MSVC warnings about control reaching end of non-void function.
L2. requested_bytes records the post-clamped value — util/rate_limiter.cc
  • Issue: Documentation concern only. requested_bytes is captured after std::max(0, bytes). Correct behavior, but a clarifying comment could help.
L3. RATE_LIMITER_BYTES_* name may be ambiguous — include/rocksdb/statistics.h
  • Issue: "Bytes granted" could be confused with GetTotalBytesThrough(). Consider clarifying in the comment that these are per-OpType counts vs. per-priority.
L4. Java histogram byte values exceed HISTOGRAM_ENUM_MAXjava/src/main/java/org/rocksdb/HistogramType.java
  • Issue: New values 0x45/0x46 > HISTOGRAM_ENUM_MAX (0x3E). Functionally fine since Java uses value-based lookup, and the pattern is already established (0x43, 0x44 exist). Pre-existing design debt.

Cross-Component Analysis

Context Affected? Notes
Custom RateLimiter subclasses No Base class 4-arg Request unchanged
WritePreparedTxnDB No Same Request API
statistics_test sanity checks Must pass PR correctly maintains TickersNameMap/HistogramsNameMap ordering
Java JNI mappings Correct No value collisions (-0x71 to -0x78 are free)
C++ enum value shift Safe Header documents values are not stable

Positive Observations

  • Mutex scope narrowing reduces contention on request_mutex_ — meaningful improvement for high-throughput I/O.
  • Clean separation of request granting (under mutex) from stats recording (outside mutex) using local flag variables.
  • Correct stop_ handling — no stats recorded for interrupted requests.
  • Backward-compatible — 3-arg legacy path defaults to kWrite; custom subclasses unaffected.
  • Stats only on delayed path — histogram and wait time recorded only when request actually waited, avoiding fast-path noise.

ℹ️ About this response

Generated by Claude Code.
Review methodology: claude_md/code_review.md

Limitations:

  • Claude may miss context from files not in the diff
  • Large PRs may be truncated
  • Always apply human judgment to AI suggestions

Commands:

  • /claude-review [context] — Request a code review
  • /claude-query <question> — Ask about the PR or codebase
@meta-codesync meta-codesync Bot closed this in 75c1ffd Jun 29, 2026
@meta-codesync

meta-codesync Bot commented Jun 29, 2026

Copy link
Copy Markdown

@xingbowang merged this pull request in 75c1ffd.

@meta-codesync meta-codesync Bot added the Merged label Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

1 participant