Provider Best Practices
Recommendations
The following best practices apply to providers. Adopting these patterns consistently ensures that your applications remain reliable, performant, and maintainable as they scale.
Single Provider Instance
Reuse provider instances rather than creating new ones for each operation.
// Good: Reuse provider
const provider = new JSONRpcProvider({
url: url,
network: network
});
const block1 = await provider.getBlock(1);
const block2 = await provider.getBlock(2);
// Bad: Creating new provider each time
const block1 = await new JSONRpcProvider({
url: url,
network: network
}).getBlock(1);
const block2 = await new JSONRpcProvider({
url: url,
network: network
}).getBlock(2);Choose the Right Provider
Use JSON-RPC provider for most use cases and WebSocket provider only when real-time updates are required.
Batch Related Operations
When querying multiple values from the same provider, batch the calls into a single operation wherever the API supports it. Methods like getBalances() accept arrays and return results in one round-trip, significantly reducing latency and RPC load compared to issuing individual requests in a loop. For multiple distinct method calls on the same contract instance, use Promise.all() to execute them concurrently instead of awaiting each one sequentially.
// Batch multiple independent requests
const [block, balance, utxos] = await Promise.all([
provider.getBlockNumber(),
provider.getBalance('bc1q...'),
provider.utxoManager.getUTXOs({ address: 'bc1q...' }),
]);Consider Cache Timing
The provider caches responses to reduce redundant network requests. For time-sensitive operations such as checking balances or UTXO availability before a transaction, ensure you are working with fresh data by bypassing or invalidating the cache.
// Good: Reuse for efficiency
const provider = new JSONRpcProvider({
url: url,
network: network
});
await provider.gasParameters();
await provider.gasParameters(); // Cached
// When fresh data is critical
const freshProvider = new JSONRpcProvider({
url: url,
network: network
});
const freshGas = await freshProvider.gasParameters();Monitor Memory
Long-running applications may accumulate cache entries.
Connection Cleanup
Always ensure providers are properly disposed when no longer required.
- Use the close() method for JSONRpcProvider.
- Use the disconnect() method for WebSocketRpcProvider.
// Good: Cleanup
// For JSONRpcProvider
try{
await provider.getBlock(1);
} finally{
await provider.close();
}
// For WebSocketRpcProvider
try{
await provider.getBlock(1);
} finally{
await provider.disconnect();
}Network Matching
Ensure the provider network matches your contract addresses.
Timeout Configuration
Select an appropriate timeouts for your use case.
const provider = new JSONRpcProvider({
url: url,
network: network,
timeout: 60000 // 60 second timeout
});Implement Retries
Use exponential backoff for transient failures.
Rate Limit
Don't overwhelm nodes with requests.
Monitor Performance
Track request times and failure rates.
Enable Threaded Parsing
For production with large responses.