Skip to content

RPC retries

Bound failover without classifying every call yourself

Every Route carries an attempt bound. The Gateway combines failure certainty with exact operation semantics to decide when another Endpoint is safe.

Open consoleRead attempt bounds

The attempt bound lives on the Route

A Route sets max_attempts, default 3, between 1 and 10, and the effective limit is the lower of the Route value and the deployment limit. Each attempt goes to a different Endpoint, and a candidate leaves the eligible set once it has been tried, so one request never hits the same upstream twice. A Route accepts up to 100 targets; the attempt bound defines the small subset any single request is allowed to walk through.

Bounded by configuration

The Route decides how many upstreams a request may try, so no call walks the whole target list.

Always a different Endpoint

Failover moves across upstreams instead of repeating the request against the one that just failed.

Per-attempt timeout

An upstream timeout bounds each attempt individually rather than the request as a whole.

Read attempt boundsExplore RPC failover

Failure certainty meets operation semantics

Connection and configuration failures can move any operation to another Endpoint. After an ambiguous timeout or interrupted response, the Gateway replays stateless queries and fixed client-signed broadcasts, while Endpoint-local, side-effecting, and unrecognized operations stop conservatively. JSON-RPC notifications are not replayed after an ambiguous access failure or non-2xx response. Matching is exact and protocol-specific instead of relying on method prefixes or HTTP verbs.

Stateless queries

Queries and simulations can continue across Endpoints after an ambiguous upstream failure.

Signed broadcasts

The same client-signed payload can be submitted to another Endpoint within the attempt bound.

Conservative unknowns

Custom and unrecognized operations stop after an ambiguous failure instead of guessing.

Review operation-aware failoverSee the final Gateway codes

What counts as a failure, and what stays final

Before returning an upstream response the Gateway checks its structure: valid JSON, a matching response id, and exactly one of result and error. A response that fails those checks counts as a failure and can move to the next candidate when the operation can be replayed safely, so a malformed 200 does not reach your application as a success. A well-formed upstream JSON-RPC application error is a different case: it is final and does not trigger failover.

Review the structural checksChoose a selection strategy

The attempt bound is a latency budget

Because each attempt carries its own upstream timeout, the bound limits how many sequential upstream timeouts can contribute to the caller's latency budget; the caller still owns the whole-request deadline. A user-facing read is usually better served by a low bound and a fast failure your application can handle, while a background job can afford to walk further down the target list. Circuit rejections do not consume attempts, so a target that is already known to be failing is skipped without spending part of the budget.

See how Circuit skips a targetOrder your own node first

Client-side backoff is still yours

Attempts run back to back. The Gateway does not wait between them, because a Route-level pause would hold your connection open while your own timeout is running. Gateway-generated rate-limit responses carry a retry hint, and the right place to space requests out is the caller: exponential backoff, random jitter, and a bounded attempt count on your side, on top of the failover the Route already performs.

Read recovery actionsSee rate limit responses

Next step

Set the bound for one Route

Choose the attempt bound that fits your latency budget; the Gateway handles operation-aware failover internally.