HarperFast / HarperFast/rocksdb-js
Dedicated read thread pool: isolate cache-miss async gets from the libuv threadpool
- Dominant language
- C++
- Stars
- 21
- Forks
- 2
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 36
Description
## Context
The commit-thread work (branch `kris/commit-thread-spike`, follow-up to the libuv starvation research) moves async transaction commits off the libuv threadpool onto a dedicated per-`DBDescriptor` commit thread. That removes the biggest starvation source: benchmarks showed heavy commits at `UV_THREADPOOL_SIZE=4` degrading an `fs.stat` probe from 0.29ms to ~15ms p50 (~50×), fully restored by the commit thread (0.12ms p50 during the same burst).
Async reads are the other RocksDB user of the libuv pool: every `get()` that misses the block cache dispatches its own `napi_create_async_work` item (`database.cpp`, async get path). Under a heavy cache-miss read burst, those can still compete with `fs`, `dns`, `crypto`, and each other on the default 4 threads — and anything else jamming the pool delays reads.
## Proposal
Generalize the `CommitWorker` into a per-database executor with two lanes:
- **Commit lane** — 1 thread, ordered (existing commit-thread design; ordering matters for the transaction log).
- **Read pool** — a small pool (default ~4, configurable) for async gets and other read-only async work. Reads are latency-sensitive and parallelizable, so they must NOT share the ordered commit lane — queueing a cache-miss get behind a multi-ms commit stall would be a regression.
Benefits: read bursts stop competing with unrelated libuv work in both directions, and read latency becomes independent of pool pressure from the rest of the process.
## Evidence gate
Lower priority than the commit lane: commits were the long-occupancy offenders, and Harper moved hot point reads to `getSync`. Before building, extend the starvation benchmark (`~/dev/scripts/rocksdb-commit-bench/` on Kris's machine — probe latency during a sustained cache-miss read burst) to confirm read-driven starvation is observable in practice. Ship behind a flag with an A/B bench either way.
---
_Filed by KrAIs (Claude Opus 4.8) on behalf of @kriszyp, from the commit-batching feasibility research (2026-07-08)._
Contributor guide
Research direction
Start by extending the starvation benchmark in ~/dev/scripts/rocksdb-commit-bench/ to measure probe latency during a sustained cache-miss read burst, then read the async get path in database.cpp and the existing commit-thread design. Done means the benchmark establishes whether read-driven starvation is observable, followed by a flagged implementation and an A/B benchmark either way.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, node.js
- Domain
- backend, databases, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100