Skip to content

Retries

Soxom includes configurable automatic retry logic with exponential backoff for transient failures.

retries:
# Enable/disable retries globally
enabled: true
# Maximum retry attempts
max_attempts: 3
# Backoff configuration
backoff:
initial_interval_ms: 500 # First retry delay
max_interval_ms: 30000 # Maximum delay cap
multiplier: 2.0 # Exponential multiplier
jitter: 0.25 # 25% randomization
# HTTP status codes to retry
retry_on:
- 408 # Request Timeout
- 429 # Too Many Requests
- 500 # Internal Server Error
- 502 # Bad Gateway
- 503 # Service Unavailable
- 504 # Gateway Timeout
# Retry on connection errors
retry_connection_errors: true
# Respect Retry-After header
respect_retry_after: true

Soxom uses exponential backoff with jitter:

delay = min(initial_interval * (multiplier ^ attempt), max_interval) * (1 ± jitter)

With default settings (initial: 500ms, multiplier: 2.0, max: 30000ms):

AttemptBase DelayWith Jitter (±25%)
1500ms375-625ms
21000ms750-1250ms
32000ms1500-2500ms
44000ms3000-5000ms
58000ms6000-10000ms
CodeNameReason
408Request TimeoutServer timed out waiting
429Too Many RequestsRate limited
500Internal Server ErrorServer error, may be transient
502Bad GatewayUpstream server error
503Service UnavailableServer temporarily unavailable
504Gateway TimeoutUpstream timeout
retries:
retry_on:
- 429
- 503
# Remove 500 if your API's 500s are not transient

Use x-soxom-retries in your OpenAPI spec:

paths:
# Disable retries for non-idempotent operations
/payments:
post:
x-soxom-retries:
enabled: false
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PaymentCreate"
# Custom retry config for batch operations
/batch/process:
post:
x-soxom-retries:
max_attempts: 5
backoff:
initial_interval_ms: 1000
max_interval_ms: 60000

Override retry settings per-request:

// Disable retries for a single request
const result = await client.users.create(data, {
retries: { enabled: false }
});
// Custom retry config
const result = await client.users.list({
retries: {
maxAttempts: 5,
backoff: {
initialIntervalMs: 1000
}
}
});

When respect_retry_after: true, the SDK respects server-provided retry timing:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

The SDK will wait 60 seconds before retrying, regardless of backoff settings.

Soxom sends a header indicating the retry attempt:

X-Soxom-Retry-Count: 2

Your server can use this for:

  • Logging and debugging
  • Different behavior for retried requests
  • Metrics and monitoring

For safe retries of mutating operations, use idempotency keys:

const result = await client.payments.create(data, {
idempotencyKey: "unique-request-id-123"
});

This allows retrying without risk of duplicate operations.

Retry settings follow this precedence (highest to lowest):

  1. Runtime - Per-request options
  2. Per-operation - x-soxom-retries in OpenAPI
  3. Global - retries in soxom.yaml
  4. Defaults - Soxom built-in defaults
  1. Disable for non-idempotent operations - Payments, order creation
  2. Use idempotency keys when retrying mutations
  3. Set reasonable max attempts - 3-5 is typical
  4. Configure jitter to prevent thundering herd
  5. Monitor retry rates in production