Add RPC client pool for concurrent API requests#4499
Draft
utxo-detective wants to merge 1 commit into
Draft
Conversation
The jsonrpc SimpleHttpTransport uses a single TCP connection behind a Mutex, which serializes all Bitcoin Core RPC calls. Under concurrent API load, this creates a staircase latency pattern where each request adds the full RPC round-trip time to queue depth. For example, with 20 concurrent /output requests each taking ~25ms for their RPC call, the last request waits 500ms due to serial queueing through the single socket. This adds a configurable pool of RPC clients (--bitcoin-rpc-pool-size, default 12) so concurrent API requests each get their own TCP connection to Bitcoin Core, enabling true parallel RPC execution. The primary `client` field is preserved for the indexer/updater which accesses it directly via `index.client`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
jsonrpccrate'sSimpleHttpTransportuses a single TCP connection behind aMutex:This serializes all Bitcoin Core RPC calls through one socket. Under concurrent API load, this creates a staircase latency pattern where each request adds the full RPC round-trip time to queue depth.
Benchmark: 20 concurrent
/outputrequestsEach request individually takes ~25ms, but they queue linearly because they all contend on the same socket mutex. The 20th request waits 500ms.
With instrumentation showing all time is in the RPC call phase (0ms for redb reads):
Solution
Add a configurable pool of RPC clients (
--bitcoin-rpc-pool-size, default 12, also configurable viaORD_BITCOIN_RPC_POOL_SIZEenv var) so concurrent API requests each get their own TCP connection to Bitcoin Core, enabling true parallel RPC execution.The primary
clientfield is preserved for the indexer/updater which accesses it directly viaindex.client.API-serving methods use
self.rpc_client()which does round-robin selection from the pool.Impact
With a pool size of N, up to N concurrent RPC calls can execute in parallel instead of serializing. For the benchmark above, 20 concurrent requests with a pool of 12+ would complete in ~50ms total instead of ~500ms.