Skip to main content

How To Make Batch Requests on Ethereum

Updated on
Dec 11, 2023

7 min read

info

Note that this guide only applies to users running their own Ethereum node locally or on a remote server. This guide does not apply to RPC requests made from a QuickNode endpoint, and making these types of batch requests with your QuickNode endpoint can lead to poorer performance. If you are using QuickNode, check out - A Guide to Efficient RPC Calls with QuickNode to learn how to achieve optimal performance with your endpoint. If you want to run your own Ethereum node, check out this QuickNode guide - How to Install and Run a Geth Node.

Overview

Batch requests are a feature of the Ethereum JSON-RPC API that allows multiple requests to be sent in a single HTTP POST request. Batch requests can be useful for reducing network latency and improving application performance by reducing the number of HTTP requests that need to be sent and processed.

What You Will Do

  • Learn about Batch Requests
  • Create a Node.js script to make Batch Requests

What You Will Need

  • A basic understanding of Ethereum and programming concepts
  • Access to an Ethereum node (you can learn how to run a node here!)
  • A terminal command window
  • Node.js Installed (version 18 >=)

What are Batch Requests?

A batch request is a JSON-RPC 2.0 request that contains an array of individual JSON-RPC requests. Each individual request is represented as a JSON object with the same fields as a regular JSON-RPC request. The requests in the batch can be of different types and can have different parameters.

When the Ethereum JSON-RPC API receives a batch request, it processes each request in the order that they appear in the array and returns an array of responses. If an error occurs during processing, the response for that request will contain an error object instead of a result object.

Alternatively, developers can also make batch requests on-chain. However, we will only focus on performing off-chain batch requests for this guide. Look out for an upcoming guide about on-chain batch requests!

Advantages of Batch Requests

Batch requests can offer several advantages over sending multiple individual requests:

  • Reduced network latency: By sending multiple requests in a single HTTP request, the latency of each individual request is reduced.
  • Improved performance: By reducing the number of HTTP requests that need to be sent and processed, batch requests can improve the overall performance of an application.
  • Atomicity: If multiple requests need to be executed together as a single transaction, batch requests can ensure that all requests are processed atomically, either all successfully or all unsuccessfully.

Making Batch Requests

The process of sending batch requests will be from an array filled with request objects. Let's get started.

In your terminal, create an empty npm project called off-chain-requests with the following command:

mkdir off-chain-requests && cd off-chain-requests && npm init -y

Then, let's install the required dependencies and create an empty index.js file:

echo > index.js

Now, let's create an index.js file and input the following code:

const endpoint = 'YOUR_LOCAL_ETHEREUM_NODE'; //e.g., http://127.0.0.1:8545
const from = parseInt(''); //input a valid block number here
const to = parseInt(''); //input a valid block number here

async function main() {

// Create an array of requests to be sent
const requests = [];
for (let i = from; i < to; i++) {
requests.push({
method: 'eth_getBlockByNumber',
params: [`0x${i.toString(16)}`, false],
// Set unique ID for each request based on its position in the array
id: i - from,
jsonrpc: '2.0'
});
}

// Send a batch request to the endpoint and wait for the response
const response = await fetch(endpoint, {
method: 'POST',
body: JSON.stringify(requests),
headers: { 'Content-Type': 'application/json' }
});

// Parse the response as JSON
const data = await response.json();

console.log(data)
}

// Call the main function and handle any errors that occur
main().catch(err => console.log(err));

Take a few moments to review the code and remember to replace the constant variables at the top with actual values. If you want to know the latest block number, you can take a look at Etherscan.

When you are ready to execute the script, save the file and run the command in your off-chain-requests root directory.

node index.js

You'll see an output similar to the JSON below:

[
{
"jsonrpc": "2.0",
"id": 0,
"result": {
"baseFeePerGas": "0x83373a3a5",
"difficulty": "0x0",
"extraData": "0x6665622d6275696c646f72",
"gasLimit": "0x1c9c380",
"gasUsed": "0xd7652d",
"hash": "0x135c16c831af901708c90e1d436d0921a7285b8af9236ebd0dc5ed8fefc5801b",
"logsBloom": "0x00ed02011524d064009118c0a500108101144c90a8014832202140948251021008a700800200c2102010000c2144048561c10500064d60668a005a080c68a608086440289c40011c4a800009001c52ef10040c5200c0600082c2e184800002034014120212805493c0a052a710101a210d80486480404ccfa1fc90308008a10813c320e42004241e942a48003288000040008421a8148208240503404062014002600800440012101000108a2016028106021a00208222640180058281a00902a244502213060d0e5f2010614587450642881000022824b24092204269822100f8120c2600400840a03081688005104ea0410010031020c11162080212044c10",
"miner": "0x4e0100d71ad71940c95710888e1d2501f72c823e",
"mixHash": "0x178c155fff0dab89f2fb26cbdd610b547c421dc00a928c783d4a9f73a11f49ee",
"nonce": "0x0000000000000000",
"number": "0x83b06c",
"parentHash": "0x5f802a0633279ecefc131d76d418b3f1143bc90191556413a1b222a3043b8aae",
"receiptsRoot": "0xe02bd262504d75d86d7e44252d7ccc30916cbafef27b6866a5496c476953c5c3",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "0x2a8bd",
"stateRoot": "0x345bcd154ea03886bde7b703898f70bdd64d8148fb1d36c1430e52d9241e4084",
"timestamp": "0x640b219c",
"totalDifficulty": "0xa4a470",
"transactions": [
"0x8c2e9224961ce00bf07a6bd0a6c0e5e282b58300ab677c1c07c98e52c5ad3b77",
"0x8001a35aa69ebf39b76073b276e8b7da1a1e6f93b1f002fc24d59d633d616867",
"0x1466ec0e7fe0dce9fdc6a591aa03191208ecdd064514d242a4beaabb89b14190",
"0x89844ea968b995c53753157930d2fc34c173a970c3b447130a008b2701025a24",
"0xc3ba403de892b94d35f6dc5a44652ae6f79030f29d6556c97a1868eebe7f53cb",
"0x38cfa6e0302348110cae70b8ac52ae221001f27440f5f287ff7484ff00a7c904",
"0xd545f05ba4a0a05a12762d6ebdfc82f15707af512d743c1ef2493d1b807112a8",
"0xa35480c0df21b03d9027e28f9f90b308c9c375bcf9dbc96f167ab1dd73f1f806",
"0xf324ec86c1cb4b9af2755114c257bb56546c5d7b1b1f23ec6837077c24637b53",
"0x5b7069d4fd36537dc46030ef8b7d3f5c194443db5b1dedce140089f105fb5ae8",
"0x7370966f3147c3bfc87a57e769170c0dbae3a5a499cca24987d75b9f7cecef82",
"0x59bad3992eb2d37c3e850dd34e074625234e3f645edf408d03c4db7df93468b3",
"0x9210c04f7e92b0ee7d41d32e58b96db6a31ce45462e78a36e075304e1944c734",
...
],
"transactionsRoot": "0x473861895c077c801efab8da4b8576846c371386b1282de2dffa33b246a1a190",
"uncles": []
}
},
...

If you receive an error related to - "ReferenceError: fetch is not defined", make sure your Node.js version is 18>=

The response above is an array of objects and as a result, this process can reduce network latency and can provide noticeable speed-ups when retrieving large volumes of independent data items.

The example above doesn't have any dependencies between requests. However, in some cases, retrieving data from a single request could require a follow-up request. For example, when obtaining all receipts for a block range using the JSON-RPC API's eth_getTransactionReceipt method, users must first get the transaction list for a block and then call eth_getTransactionReceipt for each transaction.

To facilitate this process, users can make two batch requests: the first is to retrieve the transaction hash list for all blocks in our target range, and the second is to retrieve receipt objects for all transaction hashes. You can also check out the Single Flight RPC add-on on the QuickNode Marketplace to automate this process for you. Additionally, another reference material to this type of requests can be found on the Geth documentation.

Final Thoughts

You have reached the end of this guide, so give yourself a pat on the back! You now better understand how to make batch requests on Ethereum! If you don't feel like managing your own node infrastructure and like 8x faster response times, you can leave the heavy lifting to us. Sign up for a free account here.

If you're having trouble, have questions, or want to talk about what you're building, drop us a message on Discord or Twitter!

We ❤️ Feedback!

If you have any feedback on this guide, let us know. We'd love to hear from you!

Share this guide