Is there an existing issue for this?
- I have searched the existing issues
Current behaviour
I keep having to increase rpcthreads
about everywhere I’m using bitcoind because without it it’s not very robust/performant.
Pasting verbatim my comment in bdk that just hit the same issue:
From a perspective of most workloads e.g. asking for blockchain data,
bitcoind
(andelectrs
) acts very much like database software, e.g. posgresql. Postgresql is an interesting case because it utilizes process-based model - meaning it will spawn not just a thread, but a whole process for every client connection - waaay heavier than just a thread.Even for that heavy model, the recommendations will be to limit it around around 500.
It takes many threads to saturate modern IO device. Just an example from a yt video I had on hand benchamarking filesystems. Each bar is number of workers. And these are dedicated IO-generating workers, generating heavy load in a tight loop. So in this benchmark, it will take like 4 workers. Possibly one worker is even more threads. But an rpc thread in bitcoind by necessity will be spending lots of time reading things and writing stuff to a tcp connection, doing some checks, re-encodings and what not. To actually get a maximum IO performance there will need to be a lot of them. I’d say 64 per core.
On my mostly idle laptop at this very moment there are 2k threads running:
On a modern Linux a thread is just a stack, which due to CoW optimizations will really amount to 1 or 2 pages (4K page size) of physically used memory plus a tiny (1K?) amount to track it all in the kernel.
There’s really not much to save on thread counts in a grand scheme of things.
Personally, I like to run as lots and lots of tests in parallel, especially any sort of integration and e2e tests, which tend to have lots of dead time - waiting for stuff (like disk and network IO - latency-bound things). The usual limit to this is the available memory. Additional benefit is also that it tends to expose problems more often, as all operations tend to have more … timing jitter.
So I’m really surprised that the default in
bitcoind
is 4. That’s too little even for an old generation raspberry pi.
I just noticed the comment in the code:
For each thread a thread stack needs to be allocated. By default on Linux, threads take up 8MiB for the thread stack on a 64-bit system, and 4MiB in a 32-bit system.
Only 8MiB of Virtual Memory is allocated, which doesn’t really mean anything. Due to CoW mechanism, only the parts of stack that are being used will be allocated as Physical Memory which is the one that actually matters.
Expected behaviour
NA
Steps to reproduce
NA
Relevant log output
NA
How did you obtain Bitcoin Core
Other
What version of Bitcoin Core are you using?
na
Operating system and version
na
Machine specifications
Linux