# Filesystem

> Source: `src/content/docs/agent-os/filesystem.mdx`
> Canonical URL: https://rivet.dev/docs/agent-os/filesystem
> Description: Read, write, mount, and manage files inside agentOS.

---
Every VM comes with a persistent filesystem out of the box. Files written anywhere in the VM are automatically saved to the Rivet Actor's built-in storage and restored on wake. No configuration needed.

- **Persistent by default** backed by Rivet Actor storage, up to 10 GB
- **Full POSIX filesystem** with read, write, mkdir, stat, move, delete
- **Batch operations** for reading and writing multiple files at once
- **Mount backends** for additional storage like S3, host directories, and overlays

## Mounting filesystems

The default filesystem persists automatically across sleep/wake cycles with no setup required (up to 10 GB). For larger storage or external data, mount additional filesystem drivers via the `options.mounts` config.

Each mount takes a `path` (where to mount inside the VM), a `driver` (the filesystem implementation), and an optional `readOnly` flag.

### In-memory

```ts @nocheck
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import { createInMemoryFileSystem } from "@rivet-dev/agent-os-core";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      { path: "/mnt/scratch", driver: createInMemoryFileSystem() },
    ],
  },
});

export const registry = setup({ use: { vm } });
registry.start();
```

### Host directory

```ts @nocheck
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import { createHostDirBackend } from "@rivet-dev/agent-os-core";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      { path: "/mnt/code", driver: createHostDirBackend({ hostPath: "/path/to/repo" }), readOnly: true },
    ],
  },
});

export const registry = setup({ use: { vm } });
registry.start();
```

### S3

Install `@rivet-dev/agent-os-s3` for S3-compatible storage.

#### Per-agent storage (recommended)

Use `createS3BackendForAgent` to automatically scope S3 storage by agent key. Each agent instance gets its own prefix (`agents/{key}/`) within the bucket, so you don't need to manage prefixes manually.

```ts @nocheck
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import { createS3BackendForAgent } from "@rivet-dev/agent-os-s3";
import type { AgentOsContext } from "@rivet-dev/agent-os-s3";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

function createVm(context: AgentOsContext) {
  return agentOs({
    options: {
      software: [common, pi],
      mounts: [
        {
          path: "/mnt/data",
          driver: createS3BackendForAgent(context, {
            bucket: "my-bucket",
            region: "us-east-1",
          }),
        },
      ],
    },
  });
}
```

The `AgentOsContext` object contains:

- `key` — unique identifier for the agent instance (e.g. actor ID, user ID, session ID). Used as the S3 prefix.
- `metadata` — optional key-value pairs with additional agent information.

#### Fixed prefix

For shared storage or custom prefix schemes, use `createS3Backend` with an explicit prefix.

```ts @nocheck
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import { createS3Backend } from "@rivet-dev/agent-os-s3";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      {
        path: "/mnt/data",
        driver: createS3Backend({
          bucket: "my-bucket",
          prefix: "agent-data/",
          region: "us-east-1",
        }),
      },
    ],
  },
});

export const registry = setup({ use: { vm } });
registry.start();
```

### Google Drive

Install `@rivet-dev/agent-os-google-drive` for Google Drive storage.

```ts @nocheck
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import { GoogleDriveBlockStore } from "@rivet-dev/agent-os-google-drive";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

const vm = agentOs({
  options: {
    software: [common, pi],
    mounts: [
      {
        path: "/mnt/drive",
        driver: new GoogleDriveBlockStore({
          credentials: {
            clientEmail: process.env.GOOGLE_DRIVE_CLIENT_EMAIL!,
            privateKey: process.env.GOOGLE_DRIVE_PRIVATE_KEY!,
          },
          folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
        }),
      },
    ],
  },
});

export const registry = setup({ use: { vm } });
registry.start();
```

## Filesystem operations

### Read and write

```ts @nocheck
// Write a file (string or Uint8Array)
await agent.writeFile("/home/user/hello.txt", "Hello, world!");

// Read a file (returns Uint8Array)
const content = await agent.readFile("/home/user/hello.txt");
console.log(new TextDecoder().decode(content));
```

### Batch read and write

```ts @nocheck
// Batch write (creates parent directories automatically)
const writeResults = await agent.writeFiles([
  { path: "/home/user/src/index.ts", content: "console.log('hello');" },
  { path: "/home/user/src/utils.ts", content: "export function add(a: number, b: number) { return a + b; }" },
]);

// Batch read
const readResults = await agent.readFiles([
  "/home/user/src/index.ts",
  "/home/user/src/utils.ts",
]);
for (const result of readResults) {
  console.log(result.path, new TextDecoder().decode(result.content));
}
```

### Directories

```ts @nocheck
// Create a directory
await agent.mkdir("/home/user/projects");

// List directory contents
const entries = await agent.readdir("/home/user/projects");

// Recursive listing with metadata
const tree = await agent.readdirRecursive("/home/user", {
  maxDepth: 3,
  exclude: ["node_modules"],
});
for (const entry of tree) {
  console.log(entry.type, entry.path, entry.size);
}
```

### File metadata

```ts @nocheck
// Check if a path exists
const fileExists = await agent.exists("/home/user/hello.txt");

// Get file metadata
const info = await agent.stat("/home/user/hello.txt");
console.log(info.size, info.isDirectory, info.mtimeMs);
```

### Move and delete

```ts @nocheck
// Move/rename
await agent.move("/home/user/old.txt", "/home/user/new.txt");

// Delete a file
await agent.deleteFile("/home/user/new.txt");

// Delete a directory recursively
await agent.deleteFile("/home/user/temp", { recursive: true });
```

_Source doc path: /docs/agent-os/filesystem_
