Retry
Queries are retried automatically on network errors or retryable HTTP status codes. Mutations
are never retried unless explicitly marked as idempotent.
RetryPolicy
interface RetryPolicy {
attempts: number; // max retries (excluding initial request)
delay: number | ((attempt: number) => number); // fixed ms or backoff function
retryOn?: number[]; // HTTP status codes (default: [408, 429, 500, 502, 503, 504])
}A request is retried when a network error occurs or the response status is in retryOn, up to attempts additional tries. On each retry the full onRequest hook
runs again, so dynamic headers (e.g. refreshed auth tokens) are re-evaluated.
Basic Usage
const rpc = createRpcClient({
baseUrl: "/api",
retry: { attempts: 3, delay: 1000 },
});Exponential Backoff
// Exponential backoff: 1s, 2s, 4s
const rpc = createRpcClient({
baseUrl: "/api",
retry: { attempts: 3, delay: (n) => 1000 * 2 ** (n - 1) },
});Custom Retry Logic
const rpc = createRpcClient({
baseUrl: "/api",
retry: {
attempts: 3,
delay: 1000,
retryOn: [429, 503], // only retry rate-limited or unavailable
},
});Idempotent Mutations
By default, mutations are never retried — even with a retry policy configured. To opt a mutation
into retry, mark it as idempotent in the Rust macro. This signals that repeated calls produce the same result.
// By default mutations are never retried.
// Mark a mutation as idempotent to opt in to retry:
#[rpc_mutation(idempotent)]
async fn upsert_user(input: UserInput) -> User {
// safe to retry — repeated calls produce the same result
}