patternjavascriptTip
Multicall: batching multiple read calls into a single RPC request
Viewed 0 times
viem 2.x, Multicall3
multicallMulticall3batch readviem multicallRPC optimizationperformance
Problem
Making many individual eth_call requests to read on-chain data causes waterfall latency and can hit RPC rate limits.
Solution
Use Multicall3 (deployed at the same address on all major chains) to batch calls. viem supports this natively with multicall().
const results = await client.multicall({
contracts: [
{ address: tokenA, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
{ address: tokenB, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
],
});Why
Multicall3 bundles multiple calls into a single eth_call, dramatically reducing RPC overhead and enabling atomic reads across multiple contracts.
Gotchas
- Multicall3 allows individual calls to fail independently — check each result's status field
- Very large multicall batches can exceed block gas limits — chunk requests into groups of ~100
- The Multicall3 contract is at 0xcA11bde05977b3631167028862bE2a173976CA11 on all supported chains
Code Snippets
Batch ERC-20 balance reads with viem multicall
import { createPublicClient, http, erc20Abi } from 'viem';
import { mainnet } from 'viem/chains';
const client = createPublicClient({ chain: mainnet, transport: http() });
async function getMultipleBalances(tokenAddresses, userAddress) {
const results = await client.multicall({
contracts: tokenAddresses.map(address => ({
address,
abi: erc20Abi,
functionName: 'balanceOf',
args: [userAddress],
})),
allowFailure: true,
});
return results.map((result, i) => ({
token: tokenAddresses[i],
balance: result.status === 'success' ? result.result : 0n,
}));
}Context
Building dashboards or DEXes that need to read many contract values simultaneously
Revisions (0)
No revisions yet.