# Files

Write files into a sandbox before a run, read what the agent made, and move large files in parallel chunks.

The repo is copied into every sandbox for you. Use the files API for everything else: fixtures, data, logs, or the build output you want to keep.

![Large files move in chunks over six streams at once. The destination fills as the source drains, so a 2 GB fixture lands in seconds.](/illos/transfer.svg)

## Write a file

```ts TypeScript
await sandbox.files.write("fixtures/orders.json", JSON.stringify(orders));
```

```python Python
sandbox.files.write("fixtures/orders.json", json.dumps(orders))
```

Paths are relative to the repo root. Folders are made as needed.

## Read a file

```ts TypeScript
const log = await sandbox.files.read("logs/test.log");
```

```python Python
log = sandbox.files.read("logs/test.log")
```

## Upload and download large files

For anything over a few megabytes, stream it. Uploads and downloads are split into chunks that travel in parallel, and resume where they stopped if the connection drops.

```ts TypeScript
import { createReadStream, createWriteStream } from "node:fs";

await sandbox.files.upload("data/events.parquet", createReadStream("./events.parquet"));
await sandbox.files.download("dist/app.tar.gz", createWriteStream("./app.tar.gz"));
```

```python Python
with open("events.parquet", "rb") as f:
    sandbox.files.upload("data/events.parquet", f)
with open("app.tar.gz", "wb") as f:
    sandbox.files.download("dist/app.tar.gz", f)
```

| Limit | Value |
|---|---|
| Largest single file | 5 GB |
| Sandbox disk | 20 GB on Hobby, 100 GB on Team |
| Parallel streams per transfer | 6 |

> [!NOTE]
> Files you write are part of the sandbox, not the repo. They never appear in a pull request unless the agent adds them to the diff itself.
