Retry Mechanisms for Transport Failures in Cloudflare Computer's Sync Protocol

Cloudflare Computer's sync protocol implements exponential back-off with a configurable retry limit to automatically recover from transient transport failures between the Durable Object server and the computerd client.

The @cloudflare/rpc package powers the synchronization layer that keeps filesystem state consistent across distributed components. Transport failures—network hiccups, server restarts, or temporary Durable Object unavailability—are inevitable in distributed systems. Rather than failing immediately, the sync driver embeds systematic retry logic to maintain reliability without manual intervention.

Where Transport Retry Logic Lives

The core implementation resides in packages/rpc/src/sync-driver.ts. This file defines the SyncDriver class, which orchestrates all RPC interactions between the client and the Cap'n Web server (the Durable Object).

Every sync operation—pullOnce, pushChanges, syncStatus—flows through the same resilient transport wrapper. The driver transparently handles retries so callers receive either a successful response or a propagated error after exhaustion.

The Four-Stage Retry Strategy

The sync driver's retry mechanism operates through a predictable pipeline:

  1. Transport error detection — The driver distinguishes application-level RPC failures from transport-level exceptions such as ECONNRESET, ETIMEDOUT, or broken channel indicators. Application errors return immediately; transport errors trigger retry evaluation.

  2. Exponential back-off delay — Each retry waits longer than the previous: 100 ms → 200 ms → 400 ms, following exponential growth. This prevents thundering herd problems when a recovering endpoint receives simultaneous reconnection attempts.

  3. Attempt limiting — By default, the driver retries 3 times before surfacing the error to the caller. This balances resilience against persistent failures with timely failure notification.

  4. State reset between attempts — Partial response data is cleared and the RPC stub re-initialized, ensuring each retry begins from a clean state without residual corruption from the failed attempt.

A helper function—withRetry or equivalent internal abstraction—centralizes this pattern so all sync methods inherit identical resilience guarantees without code duplication.

Practical Usage Examples

Basic Automatic Retry

The retry behavior requires no explicit configuration. Simply instantiate SyncDriver and invoke sync methods:

import { SyncDriver } from '@cloudflare/rpc';

// Connect to Durable Object stub
const driver = new SyncDriver(doStub);

// Transport failures are retried automatically
const changes = await driver.pullOnce();
await driver.pushChanges(localChanges);

Custom Retry Parameters

Advanced deployments can tune retry behavior through constructor options:

const driver = new SyncDriver(doStub, {
  maxRetries: 5,              // Increase to 5 attempts
  initialBackoffMs: 150,      // Start delays at 150 ms
  maxBackoffMs: 3000,         // Cap back-off at 3 seconds
});

These parameters adapt the driver to different network conditions—higher maxRetries for unstable links, lower maxBackoffMs for latency-sensitive operations.

Key Source Files

Understanding the complete retry implementation requires examining these locations:

Summary

  • Transport retry logic is centralized in packages/rpc/src/sync-driver.ts within the SyncDriver class
  • The mechanism uses exponential back-off (default start: 100 ms, cap: ~5 seconds) with 3 attempt limit
  • Transport errors (ECONNRESET, ETIMEDOUT, channel breaks) trigger retry; application errors do not
  • State is fully reset between attempts to prevent corruption propagation
  • Configuration options allow tuning maxRetries, initialBackoffMs, and maxBackoffMs

Frequently Asked Questions

How does the sync driver distinguish transport failures from application errors?

The driver inspects error types and codes. Application errors—such as a failed RPC method call returning a defined error response—pass through immediately. Transport errors indicating channel breakage, timeouts, or connection resets trigger the retry loop. This classification prevents wasted retries on permanent application failures.

Can I disable retries entirely for debugging purposes?

The constructor accepts maxRetries: 0, which propagates all transport errors immediately without retry. This configuration is useful for debugging transport issues or when operating in environments where immediate failure visibility is preferred over resilience.

What happens to in-flight data when a retry occurs?

The driver clears any partially-received response buffers and re-initializes the RPC stub before each retry attempt. This state reset ensures that corrupted or truncated responses from failed attempts cannot contaminate subsequent retries.

Is the retry delay blocking or concurrent?

Retry delays are implemented with non-blocking asynchronous waits, preserving the single-threaded event loop efficiency characteristic of the Workers runtime. Other sync operations or unrelated work can proceed during back-off periods.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →