7

This is a fairly simple question which (I suspect) has a more complex answer. I would like to find out that answer now rather than the hard way down the line.

How many concurrent requests can an Ethereum node handle?

If I have a Parity/Geth node processing transactions to the chain, how much can I hammer it? web3.js communicates with a node utilising the JSON RPC protocol. I assume therefore that the bottleneck is thus the client serving those requests.. I.E the node.

So, does anyone have any insight? If I threw 1,000 pre-signed transactions at the node, what would happen? 10,000? 1 million?

3
  • The title should be improved. I think the question is about RPC requests, but the title leads one to think it's about processing transactions under consensus. The answer to that question is however many fit under the block-wide gasLimit. Commented Aug 31, 2017 at 21:05
  • The question seeks to discern how many requests a node can process concurrently. The most common interface to a backend node is RPC. I am not clear as to where the confusion lies but am happy to change it if others see fit. Commented Aug 31, 2017 at 23:23
  • It could be interpreted as number of transactions. When I first clicked on it, that's what I thought. No biggy though. Commented Sep 1, 2017 at 19:24

5 Answers 5

11
+100

So we actually very, very rarely completely exploded. During big ICOs for instance we were seeing 200k transactions being sent via the MEW node in a single hour, which is about 55 TX/sec. Each transaction consists of:

  • Loading balance

  • Loading token balances

  • Getting network gas price (we no longer do this)

  • Estimating gas (each time the user changes a field)

  • Getting the nonce of an account

  • Actually sending the TX

This had us receiving ~1M requests/hour, or 277 req/s. We have seen DDOS (or dapps) hit as much as 4M requests/hour (but not for a sustained period like an ICO).

During these situations we don't necessarily crash we just have massive latency as it moves through the queue. At some point, depending on your infrastructure, you will obviously completely run out of memory and explode or refuse to accept incoming connections or timeout before it can process anything.

There is also a very large difference between the calls themselves. 5M getBalance requests is different than getting the TX hash or broadcasting a transaction or getting the nonce.

There is also a very large difference between internally attempting to getBalance or sendRawTX and accepting these calls via API / JSON RPC. Locally, we have been able to process 10k transactions in ~7sec. If we dump 10k txs in API, it takes more like 40 seconds to return the TX hash to 10k different users, as long as there aren't 10k other calls thrown in there for confusion.

So, to answer your question, the number of open files in your config file is likely the max right now, which is likely 1024. 😉

The bottlenecks appear at various points, not always the node itself. We have hit bottle necks with TX pool size, CPU, open files, and more. We currently run 10 nodes: 5 geth and 5 parity. For whatever reason, a few of us are having issues with huge latency spikes on Parity itself right now.

If you want to dive deeper, https://github.com/MyEtherWallet/docker-geth-lb

2
  • 1
    Some thoughts. Is 277 req/s distributed over the 10 nodes or per node? When you mention open files do your refer to the OS level config? Commented Aug 31, 2017 at 10:00
  • 2
    So because of differences between geth and parity and issues related to the TX pool, we route API calls based on call and best client to handle. geth and parity both handle getTransactionCount differently (one counts txs in txpool, the other doesn't) For example, token balances are always loaded over Parity. Gas, Nonce, and Send via Geth. This ensures that tokens not loading won't prevent you from sending. So, to answer your question, sorta? We only had 6 nodes running at that time.
    – tayvano
    Commented Sep 1, 2017 at 2:40
4

This question was posted quite a while ago; however, the answers seem to be somewhat outdated, as the numbers posted range in the 100's, to 1024, to under 2,000.

Here's an actual benchmark:

Parity RPC benchmark

Hardware:

Bare metal cloud server

  • CPU: E3-1270v6
  • RAM: 32GB
  • HD: SSD

This is simply a benchmark of calls to eth_blockNumber, and Parity has no problem with ~40k req/s via HTTP, and ~70k req/s via IPC, using the rust-web3 client library (version 0.2.0 at the time of this writing).

Of course, this is not indicative of real-world performance. We have a service that makes more resource intensive rpc calls (a combination of parity_pendingTransactions and trace_transaction, polling the full tx pool - not eth_getFilterChanges), and a single Parity node serves a sustained >20k req/s via the websocket endpoint (custom web3 client written in Rust, using the ws-rs websocket library, single threaded, unoptimized development code).

1
  • Great to have included a benchmark. Would be even better to have a getBalance for different addresses, as the eth_blockNumber is likely just a global state variable and not something that requires any computation on the node.
    – Symeof
    Commented Sep 12, 2018 at 16:15
3

Not sure if it helps, but my Parity node on my laptop is able to process not more than 2000 eth_call requests per second.

While importing the chain it's limited to around 200 transactions processed per second. With high-end hardware it's quite probable to reach numbers 5-10x of that, but that's nothing I have available right now.

It's worth to mention that there are so many different RPC requests available and also so many different kinds of Ethereum transactions regarding the complexity, so these numbers should be consumed with caution.

2
  • 1
    This is interesting insight. Would be interesting to get insight from the Infura people but they don't seem very open in that regard. Commented Aug 30, 2017 at 15:51
  • 1
    Called Taylor for support :D
    – q9f
    Commented Aug 31, 2017 at 9:19
2

Off topic here. It certainly won't win the bounty, but QuickBlocks hits the RPC once (it's slow) and then caches the data on disc (SSD much preferred) to be re-delivered much faster the next time it's requested.

We're seeing sustained access to the exact same data as the RPC at more than 100 times faster speeds, this on a Mac laptop and fully decentralized.

Yes--we've doubled the disc storage requirement, yes--the data is leaking out from under consensus (so is MyEtherWallet and Infura in that sense), but it's really fast, and with super-fast data we can do all sorts of interesting stuff like build cap tables for ERC20 tokens locally, analyze a contract's gas usage, etc.

1

Since there aren't any answers yet...

I would say the number, on a private chain using commodity desktop hardware, is under 10 000 and probably closer to a few hundred, depending on the nature of the transactions. A fast web server like nginx can handle somewhat more than that about that many in a single thread (see here). But the RPC calls are not as simple as serving up a static page that can be cached. Firstly, there may be dependencies for transactions which require sequential execution of transactions. This can be sped up with speculative evaluation over multiple cores. However, unless you keep the whole blockchain in RAM, you'll still need to hit the disk sometimes. A good SSD can serve on the order of 100k IOPS, but is still a big limit for databases. E.g., Lehtinen found that his SSD could crank out about 1000 tps.

Much beyond this, your computer will probably start dropping TCP connections.

As you can tell, I have not actually tested this and you should treat these numbers as such!

1
  • Why TCP connection drop? I faced this problem after increasing above 30 tps on using http provider.
    – Gopal ojha
    Commented Apr 25, 2019 at 2:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.