# How to Perform Paginated Reads with workspace.fs.readdir in Cloudflare Computer

> Learn to perform paginated reads with workspace.fs.readdir in Cloudflare Computer. Efficiently slice directory results using limit and offset options for faster operations.

- Repository: [Cloudflare/computer](https://github.com/cloudflare/computer)
- Tags: how-to-guide
- Published: 2026-09-04

---

**Use the `limit` and `offset` options in `ReaddirOptions` to slice directory results entirely on the host side without triggering remote RPC calls.**

When working with large directories in Cloudflare Computer workspaces, loading entire file listings into memory can degrade application performance. The `workspace.fs.readdir` method provides built-in pagination capabilities that let you iterate through directories in manageable chunks, with validation and slicing logic implemented directly in the filesystem layer.

## Understanding the `ReaddirOptions` Interface

The `readdir` method accepts an optional `ReaddirOptions` object that controls pagination behavior and return format. According to the implementation in [`packages/dofs/src/fs/readdir.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/fs/readdir.ts), three key options are available:

- **`limit`**: A non-negative safe integer specifying the maximum number of entries to return. The implementation validates this parameter before slicing the result set.
- **`offset`**: A non-negative safe integer indicating how many entries to skip before returning results. This enables cursor-style pagination through large directories.
- **`withFileTypes`**: A boolean that determines the return type. When `true`, the method returns an array of **`WorkspaceDirentResult`** objects containing `name`, `isFile()`, and `isDirectory()` methods. When omitted or `false`, it returns simple filename strings.

## Source Code Architecture

The pagination logic is implemented across multiple layers in the Cloudflare Computer repository:

**[`packages/dofs/src/fs/readdir.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/fs/readdir.ts)** contains the core implementation that enforces `limit` and `offset` validation and performs the array slicing on the full entry list. This low-level filesystem layer handles the actual pagination arithmetic.

**[`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts)** provides the public `Workspace` API surface. The `fs.readdir` method in this file forwards your pagination options directly to the underlying DOFS (Durable Object File System) implementation.

**[`packages/computer/src/stub.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/stub.ts)** implements `WorkspaceStub`, which proxies calls from Durable Objects or Workers. The stub implementation respects the same `limit` and `offset` options, ensuring consistent behavior across environments.

Because pagination occurs entirely within the **host-side store**, the operation does not trigger additional remote RPC calls regardless of the page size or offset depth.

## Implementing Paginated Directory Listings

The following patterns demonstrate how to implement efficient pagination using `workspace.fs.readdir`.

### Basic Pagination with String Results

This example iterates through a directory in pages of 10 entries, collecting all filenames into a single array:

```typescript
async function listAllEntries(ws: Workspace) {
  const pageSize = 10;
  let offset = 0;
  const all: string[] = [];

  while (true) {
    const page = await ws.fs.readdir("/", { limit: pageSize, offset });
    if (page.length === 0) break;
    all.push(...page.map(e => typeof e === "string" ? e : e.name));
    offset += pageSize;
  }

  return all;
}

```

### Paginating with File Type Metadata

When you need directory entry metadata, combine pagination with `withFileTypes` to receive `WorkspaceDirentResult` objects:

```typescript
async function listFilesWithTypes(ws: Workspace) {
  const pageSize = 5;
  let offset = 0;
  const results: WorkspaceDirentResult[] = [];

  while (true) {
    const page = await ws.fs.readdir("/", {
      limit: pageSize,
      offset,
      withFileTypes: true,
    });
    if (page.length === 0) break;
    results.push(...page);
    offset += pageSize;
  }

  return results.filter(d => d.isDirectory());
}

```

### Handling Invalid Pagination Parameters

The implementation validates that `limit` and `offset` are non-negative safe integers. Attempting to use negative values throws validation errors:

```typescript
async function safeRead(ws: Workspace) {
  try {
    // Throws because offset must be ≥ 0
    await ws.fs.readdir("/", { limit: 5, offset: -1 });
  } catch (e) {
    console.error("Invalid pagination parameters:", e);
  }
}

```

## Performance Benefits of Host-Side Pagination

Because the pagination logic in [`packages/dofs/src/fs/readdir.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/fs/readdir.ts) operates on the host-side store, you can page through extremely large directories without the network overhead typically associated with distributed filesystems. The entire entry list exists in memory on the host, and the `limit`/`offset` parameters simply slice this array before returning results to your application.

This architecture ensures that requesting page 1000 of a directory costs the same as requesting page 1, with no additional latency from remote storage calls. The `WorkspaceStub` implementation maintains this guarantee when proxying calls from Durable Objects or Workers, as verified in the test suite.

## Summary

- **`workspace.fs.readdir`** accepts `limit` and `offset` options through the `ReaddirOptions` interface to enable efficient pagination.
- The core pagination logic resides in **[`packages/dofs/src/fs/readdir.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/fs/readdir.ts)**, while **[`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts)** exposes it through the public API.
- Set **`withFileTypes: true`** to receive `WorkspaceDirentResult` objects instead of plain strings.
- Pagination is performed entirely on the **host-side store**, eliminating RPC overhead for large directories.
- Both `Workspace` and `WorkspaceStub` implementations respect these options consistently.

## Frequently Asked Questions

### What parameters does workspace.fs.readdir accept for pagination?

The method accepts `limit` and `offset` parameters through the `ReaddirOptions` object. Both must be non-negative safe integers. `limit` controls the maximum number of entries returned, while `offset` specifies how many entries to skip at the beginning of the directory listing.

### Does pagination work when withFileTypes is enabled?

Yes. When you set `withFileTypes: true`, each page contains `WorkspaceDirentResult` objects instead of strings. Each object includes the entry `name` and methods like `isFile()` and `isDirectory()`, allowing you to filter by type within your pagination loop.

### Where is the pagination logic implemented?

The actual slicing and validation logic is implemented in **[`packages/dofs/src/fs/readdir.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/fs/readdir.ts)**. The public `Workspace` class in **[`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts)** forwards your options to this underlying implementation. This architecture ensures consistent behavior whether you are using a direct workspace connection or the `WorkspaceStub` proxy.

### Can I use negative values for offset to read from the end of a directory?

No. The implementation in [`packages/dofs/src/fs/readdir.ts`](https://github.com/cloudflare/computer/blob/main/packages/dofs/src/fs/readdir.ts) validates that both `limit` and `offset` are non-negative safe integers. Passing negative values will cause the method to throw a validation error before performing the directory read.