Retry Logic

Handle transient failures automatically with exponential backoff and jitter.

Overview

RelayPlane includes built-in retry logic that automatically handles rate limits, network timeouts, and transient server errors. The retry system uses exponential backoff with jitter to prevent thundering herd problems and maximize throughput.

Configuration

Configure retry behavior per step using the retry option:

1import { relay } from "@relayplane/sdk";
2
3const result = await relay
4 .workflow("my-workflow")
5 .step("extract", {
6 retry: {
7 maxRetries: 3, // Maximum retry attempts
8 backoffMs: 1000, // Base delay between retries (ms)
9 }
10 })
11 .with("openai:gpt-4o")
12 .prompt("Extract data from: {{input.text}}")
13 .run({ text: "..." });

Options

  • maxRetries (number) - Maximum number of retry attempts (default: 0)
  • backoffMs (number) - Base delay in milliseconds (default: 1000)

Backoff Algorithm

The retry system uses exponential backoff with jitter:

1delay = baseDelay × 2^attempt × (1 ± 20% jitter)
2
3Example with backoffMs: 1000:
4 Attempt 1: ~1000ms (800-1200ms)
5 Attempt 2: ~2000ms (1600-2400ms)
6 Attempt 3: ~4000ms (3200-4800ms)
7 Attempt 4: ~8000ms (6400-9600ms)
The ±20% jitter prevents multiple failing requests from retrying at exactly the same time, which helps avoid overwhelming the API during recovery.

Recoverable Errors

The retry system automatically detects and retries these error types:

  • Rate Limits - HTTP 429 or rate_limit_exceeded errors
  • Timeouts - Network timeouts and request timeouts
  • Server Errors - HTTP 5xx responses
  • Network Errors - Connection resets, DNS failures
Authentication errors (401), validation errors (400), and other client errors are not retriedas they indicate issues that won't resolve with retries.

Complete Example

1import { relay } from "@relayplane/sdk";
2
3const result = await relay
4 .workflow("resilient-extraction")
5 .step("extract", {
6 retry: { maxRetries: 3, backoffMs: 1000 },
7 systemPrompt: "Extract key information as JSON"
8 })
9 .with("openai:gpt-4o")
10 .step("validate", {
11 retry: { maxRetries: 2, backoffMs: 500 },
12 systemPrompt: "Validate the extracted data"
13 })
14 .with("anthropic:claude-sonnet-4-20250514")
15 .depends("extract")
16 .run({ document: "..." });
17
18// Check if any retries occurred
19for (const step of result.steps) {
20 if (step.retryCount > 0) {
21 console.log(`Step ${step.stepName} retried ${step.retryCount} times`);
22 }
23}