Overview
Declared eth_calls are a performance optimization technique that allows you to pre-declare contract calls in your subgraph manifest. Instead of making synchronous RPC calls during event processing, the indexer executes these calls ahead of time and caches the results in memory. This dramatically improves indexing performance by eliminating RPC latency from your handler execution.How it works
When you declare an eth_call in your subgraph manifest, the indexing engine follows this optimized workflow:- Pre-execution: Before processing events, the indexer identifies all declared eth_calls for the current block
- Batch fetching: All declared calls are executed in parallel against the blockchain
- In-memory caching: Results are stored in an efficient in-memory cache
- Handler access: When your handler code binds to a contract and makes a call, it retrieves the cached result instantly instead of making an actual RPC call
Requirements
To use declared eth_calls, ensure yoursubgraph.yaml specifies the correct version:
subgraph.yaml
Implementation guide
Step 1: Identify candidate calls
Look for contract calls in your handlers that:- Are called frequently during event processing
- Access the same contract method repeatedly
- Contribute to slow indexing performance
- Getting token metadata (name, symbol, decimals)
- Checking user balances or allowances
- Reading contract configuration values
- Fetching owner or admin addresses
Step 2: Declare the call in your manifest
Add anethereum/call handler for each contract call you want to optimize. Here’s an example for tracking token prices from a Uniswap V3 pool:
subgraph.yaml
Step 3: Create handler functions
Your handler functions should follow this pattern. Note that the handlers themselves don’t need to perform complex logic - they primarily serve to register the calls:src/mapping.ts
Best practices
Only declare calls that are actually needed
Only declare calls that are actually needed
Each declared call adds overhead during the pre-execution phase. Only declare calls that your handlers will actually use during event processing.
Use try_call patterns for safety
Use try_call patterns for safety
Always use the
try_ prefix when calling contract methods in your handlers. This ensures your subgraph continues indexing even if a call fails or reverts.Consider call frequency vs. overhead
Consider call frequency vs. overhead
Declared eth_calls are most effective for calls that happen frequently. If a call only happens once per block or less, the overhead of declaring it may outweigh the benefits.
Monitor indexing performance
Monitor indexing performance
Use Goldsky’s dashboard to compare indexing speeds before and after implementing declared eth_calls. You should see significant improvements in blocks per second.
Performance impact
The performance benefits of declared eth_calls depend on several factors:- Call frequency: More frequent calls see greater benefits
- RPC latency: Higher latency networks benefit more from caching
- Handler complexity: Handlers with multiple contract calls see the most improvement
After implementing declared eth_calls, you should see faster indexing speeds and reduced RPC load in your deployment metrics.
Example implementation
Check out our complete example implementation showing declared eth_calls in action with an ERC-20 token subgraph on the Taiko network.Troubleshooting
Calls still seem slow after declaring
Calls still seem slow after declaring
Ensure your
specVersion is set to 1.2.0 or higher. Older spec versions don’t support declared eth_calls and will fall back to standard synchronous calls.Handler not receiving cached results
Handler not receiving cached results
Verify that your call handler function signature matches the declared function in your manifest. Mismatched signatures prevent the caching mechanism from working correctly.
Indexing errors after adding declared calls
Indexing errors after adding declared calls
Check that the contract ABI includes all the functions you’ve declared. Missing function definitions will cause indexing to fail.