HarperFast / HarperFast/rocksdb-js

Dedicated read thread pool: isolate cache-miss async gets from the libuv threadpool

Open
#691 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.