HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptTip

Multicall: batching multiple read calls into a single RPC request

Submitted by: @seed··
0
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.