# How the Compute Budget Works with 10 GB Workspace Storage Limits in Cloudflare Computer

> Understand Cloudflare Computer's compute budget and 10 GB workspace storage limits. Learn how CPU time, RPC payloads, and data sync work together.

- Repository: [Cloudflare/computer](https://github.com/cloudflare/computer)
- Tags: deep-dive
- Published: 2026-08-14

---

**The compute budget and workspace storage limits operate as independent resource constraints: the compute budget caps CPU time and RPC payload sizes (~5 MiB), while the I/O budget governs how much data can be synced per operation (~1 GB), allowing workspaces to grow to approximately 10 GB through incremental sync calls.**

In the **Cloudflare Computer** platform, understanding how these two budgets interact is essential for building applications that handle large workspaces efficiently. This guide breaks down the technical implementation, enforcement points, and practical patterns for staying within both limits.

## Understanding the Two Independent Budgets

Cloudflare Computer enforces two distinct resource boundaries that developers must navigate:

| Resource | What It Limits | Enforcement Location |
|----------|---------------|----------------------|
| **Compute budget** | CPU-time and RPC payload size between the Worker host and `computerd` container | [`packages/computer/src/runtime/bridge.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/runtime/bridge.ts) |
| **Workspace I/O budget** | Total bytes transferred during a single sync operation | [`packages/computer-rpc/src/sync-driver.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer-rpc/src/sync-driver.ts) |

### Compute Budget: Payload and CPU Limits

The compute budget is refreshed for every request. This means a long-running script can make many incremental calls as long as each individual call stays under the payload threshold.

In [`packages/computer/src/runtime/bridge.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/runtime/bridge.ts) (lines 512-516), the RPC layer enforces `maxPayloadBytes`:

```typescript
// Bridge code truncates payloads to stay under compute budget
const maxPayloadBytes = 5 * 1024 * 1024; // ~5 MiB

// Outbound messages are automatically trimmed if they exceed this limit

```

This limit applies to **any RPC payload** traveling between the host Worker and the containerized environment. Error messages, sync chunks, and other data structures all pass through this enforcement point.

### Workspace I/O Budget: Sync Transfer Limits

The I/O budget, implemented in [`packages/computer-rpc/src/sync-driver.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer-rpc/src/sync-driver.ts), controls how much data moves in a single sync round. The default **I/O byte budget is approximately 1 GB per sync**, independent of the compute budget.

## How the Budgets Interact During Sync Operations

### 1. Sync Push/Pull Respects I/O Byte Budget

When a workspace issues `push()` or `pull()`, the driver calls `pushOnce()` or `pullOnce()` internally. These methods serialize writes until the byte budget is exhausted:

```typescript
// Conceptual flow inside the sync driver
async function pushOnce(entries: Entry[]): Promise<number> {
  let bytesSent = 0;
  let entriesProcessed = 0;
  
  for (const entry of entries) {
    const entryBytes = estimateSize(entry);
    
    // Check against I/O budget (~1 GB)
    if (bytesSent + entryBytes > IO_BYTE_BUDGET) {
      break; // Stop and return progress; caller can issue another sync
    }
    
    // Additional check: ensure chunk fits compute payload limit
    if (entryBytes > MAX_PAYLOAD_BYTES) {
      // Split into smaller pieces before RPC transmission
      await sendChunked(entry);
    } else {
      await sendOverRpc(entry);
    }
    
    bytesSent += entryBytes;
    entriesProcessed++;
  }
  
  return entriesProcessed;
}

```

Once the I/O budget is hit, the operation returns the number of entries processed. The caller then issues another sync call. This prevents a single request from attempting to transfer terabytes of data, which would also exceed the compute payload limit.

### 2. RPC Payloads Must Respect Compute Budget

Every sync chunk that crosses the RPC channel passes through the bridge enforcement. The [`runtime/bridge.ts`](https://github.com/cloudflare/computer/blob/main/runtime/bridge.ts) implementation trims error messages and other payloads to stay under `maxPayloadBytes`.

If a sync chunk exceeds the compute payload limit, the driver **automatically splits the batch** into smaller pieces before transmission. This two-layer protection ensures that:

- The I/O budget prevents unbounded memory growth during sync planning
- The compute budget prevents individual RPC failures from oversized payloads

### 3. Workspace Size vs. Transfer Limits

A critical distinction: **workspace size limits are measured in bytes, not compute**. A workspace can grow to approximately 10 GB of stored files, but the I/O budget caps how much transfers in a single sync request.

| Scenario | Compute Impact | I/O Impact |
|----------|---------------|------------|
| Many small files | Low (small payloads) | Low (under 1 GB batch) |
| Single large file | Medium (chunked transfer) | Medium (counted toward 1 GB) |
| 10 GB full workspace sync | High (many RPC calls) | Capped at 1 GB per call, requiring iteration |

## Practical Code Examples

### Pushing a Large Workspace Incrementally

```typescript
import { Workspace } from "@cloudflare/computer";

async function pushAll(ws: Workspace): Promise<void> {
  let totalPushed = 0;
  let round = 0;
  
  do {
    // Each call respects both budgets automatically
    const pushed = await ws.push();
    totalPushed += pushed;
    round++;
    
    console.log(`Round ${round}: pushed ${pushed} entries (total: ${totalPushed})`);
    
    // Continue until no more pending changes
  } while (pushed > 0);
}

```

The sync driver handles chunking internally. Each `push()` call stays under the compute payload limit (~5 MiB) and the I/O byte budget (~1 GB).

### Pulling with Budget Awareness

```typescript
async function pullAll(ws: Workspace): Promise<void> {
  let result;
  
  do {
    result = await ws.pull();
    
    console.log(
      `Applied ${result.applied} entries, ` +
      `${result.skipped.length} read-only entries skipped`
    );
    
    // result.skipped indicates entries that couldn't be applied
    // due to permissions or conflicts, not budget limits
  } while (result.applied > 0 || result.skipped.length > 0);
}

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`packages/computer/src/runtime/bridge.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/runtime/bridge.ts) (lines 512-516) | Truncates RPC payloads to `maxPayloadBytes` |
| [`packages/computer-rpc/src/sync-driver.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer-rpc/src/sync-driver.ts) | Implements `pushOnce()`/`pullOnce()` with I/O byte budget enforcement |
| [`packages/dofs/src/sync/apply.test.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/apply.test.ts) | Verifies sync batches respect configurable byte budgets |
| [`docs/19_performance.md`](https://github.com/cloudflare/computer/blob/main/docs/19_performance.md) | Documents compute budget limits and I/O budgeting for workspace sync |

## Performance Characteristics

According to [`docs/19_performance.md`](https://github.com/cloudflare/computer/blob/main/docs/19_performance.md), you'll observe these patterns in practice:

- **Fast operations**: Many small files transfer quickly (low compute, low I/O)
- **Slower operations**: Large batches approaching the I/O budget require more RPC calls and CPU
- **Predictable scaling**: The ~10 GB workspace limit is achievable through iterative sync, not single-call transfer

The budget independence means you can optimize separately: reduce payload sizes for compute efficiency, or increase sync call frequency for I/O-bound workflows.

## Summary

- **Compute budget** (~5 MiB payload, per-request CPU) is enforced in [`runtime/bridge.ts`](https://github.com/cloudflare/computer/blob/main/runtime/bridge.ts) and refreshed on each request
- **I/O byte budget** (~1 GB per sync) is enforced in [`sync-driver.ts`](https://github.com/cloudflare/computer/blob/main/sync-driver.ts) via `pushOnce()`/`pullOnce()`
- Workspaces can reach ~10 GB through **incremental sync calls**, each respecting both limits
- The driver automatically chunks data to satisfy both constraints—no manual batching required
- Independent budgets allow separate optimization for RPC efficiency vs. transfer throughput

## Frequently Asked Questions

### What happens if a single file exceeds the compute payload limit?

The sync driver automatically splits oversized entries into smaller chunks before RPC transmission. According to [`packages/computer-rpc/src/sync-driver.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer-rpc/src/sync-driver.ts), this transparent chunking ensures individual RPC calls stay under `maxPayloadBytes` while the overall file still transfers correctly.

### Can I adjust the I/O byte budget for my workspace?

The default ~1 GB I/O budget is configured internally. While [`packages/dofs/src/sync/apply.test.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/sync/apply.test.ts) shows tests with configurable byte budgets for validation purposes, production workloads should design around the documented defaults and use iterative sync patterns rather than attempting to raise limits.

### Why are compute and I/O budgets separate rather than combined?

Separation allows precise resource accounting. CPU-time and payload size affect the Worker host and `computerd` container directly, while I/O volume primarily impacts storage backend costs and sync latency. Independent budgets let Cloudflare optimize pricing and performance characteristics separately, as detailed in [`docs/19_performance.md`](https://github.com/cloudflare/computer/blob/main/docs/19_performance.md).

### How do I monitor which budget is constraining my sync?

Currently, the `push()` and `pull()` methods return entry counts, not byte metrics. For debugging, instrument your code to track cumulative entries between calls and correlate with workspace size. Frequent small batches suggest compute pressure; fewer large batches with long durations suggest I/O budget saturation.