Recover from temporary failures without duplicating work, and keep stored data correct when the chain reorganizes. Match each retry to the kind of request, and store enough block identity to undo data from replaced blocks.
Prerequisites
- A retry budget for your request path.
- Logging for method, network, block reference, HTTP status, and JSON-RPC error code.
- A durable cursor for long-running log or WebSocket workflows.
Retry guidance
| Request type | Retry guidance |
|---|---|
| Current-state reads | Retry 429, 502, 503, and 504 with backoff and jitter. |
| Historical reads | Retry smaller ranges when a request times out or returns too much data. |
eth_call simulations | Retry transport failures; treat EVM reverts as application results. |
eth_sendRawTransaction | Retry the same signed transaction; do not mutate and resubmit blindly. |
| Batch requests | Retry failed items individually. |
| WebSocket subscriptions | Reconnect, resubscribe, and backfill missed blocks. |
For every retry:
- Use exponential backoff with jitter, and cap the total retry time.
- Log the method, network, block reference or range, HTTP status, and JSON-RPC error code.
- Pass the same explicit block number or hash when the retry must observe the same state as the
first attempt. A retried
latestread can land on a newer block.
See API integration for the meaning of each status and error code.
Handle reorgs
Recent blocks can be replaced by a chain reorganization. Logs you already processed from those blocks no longer describe the chain, and the replacement blocks can contain different logs.
- Key stored logs by
(blockHash, transactionHash, logIndex). The block hash keeps logs from a replaced block distinct from logs in its replacement. - Over a WebSocket
logssubscription, treat each log withremoved: trueas a reversal and delete or undo the matching stored log. - When you poll with
eth_getLogs, keep the block hashes of recent blocks you processed. Compare them witheth_getBlockByNumberon each poll, and replay from the last block whose hash still matches. - For settlement, accounting, or other irreversible steps, act only on data at or behind the
finalizedblock. Usesafewhen you can accept a small reorg risk for lower latency.