# Sandboxes

A sandbox is an isolated machine for an agent or any other program. It runs your image, or isolance's Default one, with the command, variables and size you give it. It keeps the directories you choose between stops and restarts, stops by itself when idle and starts again when work arrives. It serves the ports you list at its provider's own URLs, reaches only the hosts you allow, gets your connectors' keys added to its requests without ever holding them, and takes snapshots you can restore.

This guide covers a sandbox's whole life in the console, the CLI and the API. The CLI examples assume you've installed and configured `caas` (see [The CLI](/docs/cli)); the API examples send an API key as `$CAAS_API_KEY` (see [The API](/docs/api)).

## Create a sandbox

### In the console

1. Open **Sandboxes** and choose **New sandbox**. (The button shows for a workspace's owners and operators.)
2. Under **1. Choose a provider**, keep **Auto** to let isolance pick where the sandbox runs, or pick a provider.
3. Under **2. Choose an image**, pick **Default** or **Your image** (see [Images](#images)). Optionally enter a **Command** for the sandbox to run, and **Environment variables**, one `NAME=value` per line.
4. Under **3. Configure**, optionally enter a **Name** and pick a **Size** from those offered (see [Sizes](#sizes)). Keep **Keep state between restarts** checked to keep the **State directory** (`/workspace` unless you change it) across stops and restarts, or uncheck it to start fresh every time. **Labels**, one `key=value` per line, show only while a connector's **Reaches** names a label of your own: they decide which of those connectors the sandbox gets.
5. Under **4. Network**, list the **Allowed outbound hosts**, one per line, or leave the field empty to allow every host (see [Outbound access](#outbound-access)). The hosts of the connectors the sandbox gets show as **Included with its connectors**, and a line such as **Gets GitHub, Linear** names those connectors. Optionally enter a **User**: one of your own users, whose own accounts the sandbox then uses (see [Connectors](/docs/connectors)). Where the page says **This sandbox gets no connectors.**, keys can't be added to its requests where it would run.
6. Choose **Create sandbox**.

The sandbox's page opens. Its status moves from **Creating** to **Starting** to **Running**.

### With the CLI

```sh
caas sandboxes create --name build-agent --size l --egress api.github.com --label team=ci
```

Every field of the sandbox has its own option; see [Fields](#fields). Add `--from .` to put your Git repository's committed files in its working directory once it runs. `caas run` is the shortcut that creates a sandbox, waits until it runs, and runs one command in it:

```sh
caas run --from . --name build-agent -- npm test
```

### With the API

```sh
curl https://api.caas.sh/v1/sandboxes \
  -H "Authorization: Bearer $CAAS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "image": "default" }'
```

`{"image": "default"}` is a whole request: every other field takes its default. The answer, `201 Created`, is the sandbox with `"state": "creating"`; its first start runs on its own. A sandbox started for one of your users who hasn't signed in to a connector they sign in to with a code, such as Codex (ChatGPT), also answers their code in `signIn` (see [Sign users in with a code](/docs/connectors#sign-users-in-with-a-code)). Send the same `Idempotency-Key` again to retry safely: you get the same sandbox, never a second one.

## Fields

A sandbox is one flat object: the fields you set and the fields isolance reports side by side.

| Field | Default | Rules | CLI option | A change takes effect |
| --- | --- | --- | --- | --- |
| `name` | `sbx-` and 12 hex digits of the ID | See [Names](#names) | `--name` | Can't change |
| `image` | `"default"` | `"default"`, or your image pinned to its digest; see [Images](#images) | `--image` | At the next start |
| `command` | `null`: the image's own entrypoint and command, if it has any | 1 to 32 arguments of up to 512 characters | `--command "CMD"` | At the next start |
| `env` | `{}` | Up to 64 variables; names of letters, digits and `_`, not starting with a digit or `CAAS_`; values up to 4,096 characters | `--env NAME=VALUE` | For new commands at once; for its own command at the next start |
| `workdir` | `"/workspace"` | An absolute path, not under `/proc`, `/sys` or `/dev` | `--workdir` | Can't change |
| `size` | `"m"` | See [Sizes](#sizes) | `--size` | At the next start |
| `volumes` | `[{ "path": "/workspace" }]` | Up to 8 directories, none inside another, not `/` or under `/proc`, `/sys`, `/dev` or `/etc`; `[]` keeps nothing | `--volume PATH`, `--no-volumes` | At the next start |
| `ports` | `[]` | Up to 16 `{ "port", "public" }`, each port from 1024 to 65535; see [URLs](#urls) | `--port N[:public]` | At once |
| `egress` | `["*"]`: every host | `["*"]`, or up to 32 hosts; `[]` reaches none | `--egress HOST`, `--no-egress` | At once, but a change between `*` and a list at the next start |
| `user` | `null` | One of your own users, by your ID for them: 1 to 256 characters, without control characters; the sandbox then uses that user's own accounts (see [Connectors](/docs/connectors#whose-account-a-sandbox-uses)) | `--user` | Can't change |
| `idleStopMinutes` | `15` | 5 to 240 | `--idle-stop` | At once |
| `labels` | `{}` | Up to 16 `key: value`; keys of lowercase letters, digits, `.`, `_`, `/` and `-`; values up to 256 characters; no key starts with `caas.sh/`. They also pick its connectors | `--label KEY=VALUE` | At once; the connectors they pick at the next start |
| `provider` | `"auto"` | Where the sandbox runs: `auto` (isolance picks one at each start), or one that can run it: `cloudflare` (Native, isolance's own account), or `maritime`, `daytona`, `freestyle` or `e2b`, which run only on your own account, with your own key | `--provider` | At the next start |

A sandbox runs its `command` at every start, in its working directory and in place of the image's entrypoint and command; its output is the sandbox's [log](#read-the-log). With `command` `null`, the image's own entrypoint and command run the same way, and an image without any, such as the Default image, runs nothing until you send it commands. Each command you [run in the sandbox](#run-commands), such as the one `caas run` takes after `--`, runs once beside it and is never its `command`.

And what isolance reports:

| Field | What it is |
| --- | --- |
| `id` | The sandbox's ID, a UUID |
| `state` | `creating`, `starting`, `running`, `stopping`, `stopped`, `failed` or `deleting` |
| `stateMessage` | Why it's stopped or failed, such as `stopped by its owner` or the reason a start failed; `null` while it runs |
| `providerId` | The provider's own ID for the sandbox, `null` until it exists |
| `connectors` | `[{ "id", "name", "hosts", "account" }]`: the connectors it has, and whose account each uses (`user`, `workspace`, or `null` for a tool with no sign-in). You can't set it: each connector's **Reaches** picks its sandboxes |
| `urls` | `[{ "port", "url" }]`: the provider's own URL of each port it gives one for, while the sandbox runs; see [URLs](#urls) |
| `pendingRestart` | The fields a running sandbox takes only at its next start, and `connectors` when the connectors it would get have changed |
| `createdAt`, `startedAt`, `stoppedAt` | Milliseconds since the Unix epoch |
| `usage` | Since when it runs, its cost per hour now, and today's cost and egress, in micro-USD and bytes |

A label whose key starts with `caas.sh/` is isolance's own: a sandbox with a user carries `caas.sh/user` with the user's ID, and a sandbox that hosts an MCP server carries `caas.sh/mcp-server` with the server's ID. You can filter by them, and a connector's **Reaches** can name them, but you can't set them.

## Images

### The Default image

The Default image is Alpine Linux with bash, coreutils, Node and Docker. It runs on any size and has no command of its own: without a `command`, the sandbox runs and waits for the commands you send it. It doesn't include your project's dependencies or a coding agent: install what you need with a command, or build your own image. To install Alpine packages with `apk`, allow `dl-cdn.alpinelinux.org`.

### Your own image

You can run any `linux/amd64` image you've pushed to your workspace's namespace of the registry, `registry.caas.sh/<tenant-id>/NAME`; [Images and the registry](/docs/images) shows how. A sandbox on your own image needs size M or larger, or a custom size with at least 4 GiB of memory and 8 GB of disk. Without a `command`, the image's own entrypoint and command run.

- In the console, pick **Your image** and enter the image by digest, `registry.caas.sh/<tenant-id>/NAME@sha256:…` (`docker push` prints the digest).
- The CLI also takes a tag, and pins it to its digest for you: `caas sandboxes create --image agent:1.2.0`.
- The API takes the digest reference: `"image": "registry.caas.sh/<tenant-id>/agent@sha256:…"`. isolance checks that it's in your registry when you create the sandbox.

## Sizes

A size sets the vCPU, memory and disk the sandbox gets:

| Size | vCPU | Memory | Disk |
| --- | --- | --- | --- |
| XS | 1/16 | 256 MiB | 2 GB |
| S | 1/4 | 1 GiB | 4 GB |
| M (default) | 1/2 | 4 GiB | 8 GB |
| L | 1 | 6 GiB | 12 GB |
| XL | 2 | 8 GiB | 16 GB |
| 2XL | 4 | 12 GiB | 20 GB |

A custom size takes whole numbers: 1 to 4 vCPU, at least 3 GiB of memory per vCPU and at most 12 GiB, and 2 to 20 GB of disk. In the console, pick **Custom** and fill in **vCPU**, **Memory (GiB)** and **Disk (GB)**. With the CLI, `--size custom --vcpu 2 --memory 8 --disk 16`; in the API, `"size": { "cpu": 2, "memoryGiB": 8, "diskGB": 16 }`.

While it runs on Native, a sandbox bills for its vCPU, memory and disk, whether it's busy or waiting. On your own Daytona, Freestyle, Maritime or E2B account, that provider bills its compute and egress instead. A stopped one bills only for its snapshots. See [pricing](/pricing.html) for the rates.

## Names

A sandbox's name is unique in your workspace. It's a lowercase letter, then up to 49 lowercase letters, digits and hyphens, not ending with a hyphen. Without a name, isolance gives the sandbox `sbx-` and 12 hex digits of its ID. A name another of your sandboxes has is refused with `409 name_taken`; other workspaces can use the same names.

Every CLI command and API path takes a sandbox's ID or its name.

## Change a sandbox

In the console, the sandbox's **Network** card has an **Edit** link for its ports and outbound hosts (its connectors are listed there, read-only), and the **Public** checkbox in **Details** sets its ports' `public`; see [URLs](#urls). With the CLI, `caas sandboxes update` replaces each field you give, and a `--no-…` flag empties one:

```sh
caas sandboxes update build-agent --size xl --egress api.github.com --egress pypi.org --idle-stop 60
caas sandboxes update build-agent --no-ports --label team=web
```

With the API, `PATCH /v1/sandboxes/<sandbox>` takes the fields to replace: `env`, `ports`, `egress`, `idleStopMinutes`, `labels`, `image`, `command`, `size` and `volumes`. `name`, `workdir`, `user` and `provider` can't change.

A running sandbox takes most changes at once (see [Fields](#fields)). The others wait for its next start, and the answer's `pendingRestart` lists them; the console shows a notice and a **Restart** button. Restart it to apply them now:

```sh
caas sandboxes restart build-agent
```


## Start, stop and restart

Stop a sandbox with **Stop** on its page or in its row's menu in **Sandboxes**, `caas sandboxes stop <sandbox>`, or `POST /v1/sandboxes/<sandbox>/stop`. Start it with **Start**, `caas sandboxes start <sandbox>`, or `POST …/start`. `restart` stops it and starts it again, and takes every change that was waiting. Each answers within about 25 seconds: `200` with the sandbox once it's done, or `202` while it's still changing.

A sandbox keeps its volumes as it stops and gets them back when it starts. A stopped sandbox bills for no vCPU, memory or disk, only for storing its snapshots.

### Idle stop

A running sandbox stops by itself after `idleStopMinutes` (15 by default) without activity. Commands, a command still running, file transfers, and requests to its MCP endpoint count as activity. Requests to its [URLs](#urls) go to its provider, not through isolance, so they don't.

### Wake on request

A sandbox that stopped while idle starts again by itself when a command, a file transfer or a request to its MCP endpoint arrives. A sandbox you stopped yourself stays stopped until you start it; a command or file transfer sent to it meanwhile gets `409 not_running`.

A sandbox also starts only while the workspace has a card on file and a balance above $0. At $0, its sandboxes stop until funds arrive; see [Billing and usage](/docs/billing).

### Keep state, or start fresh

A sandbox keeps its `volumes` between stops and restarts; by default that's `/workspace`. A sandbox with `volumes: []` (the console's **Keep state between restarts** unchecked, or `--no-volumes`) starts with fresh directories every time. You can still take snapshots of it yourself and restore one.

## Run commands

A command runs one executable with its arguments, without a shell, in the sandbox's working directory, with its variables and the ones you add. To use shell features, run a shell: `sh -c 'npm ci && npm test'`. A command sent to a sandbox that stopped while idle starts it first.

### In the console

On the sandbox's page, **Run a command** takes a **Command** and a **Time limit** (1 minute to 2 hours; 10 minutes by default). Quote arguments that contain spaces. The result shows the command's state, exit code and output, with **Refresh** and, while it runs, **Cancel**.

### With the CLI

```sh
caas sandboxes exec build-agent -- node --version
caas sandboxes exec build-agent --env NODE_ENV=test --workdir /workspace/app --timeout 1800 -- npm test
echo '{"q": 1}' | caas sandboxes exec build-agent --stdin -- node read-input.js
```

`exec` waits for the command, prints its output, and exits with the command's exit code when it fails. `--timeout` takes 1 to 7,200 seconds (600 by default). With `--detach`, it returns at once with the exec's ID (and a detached command may run up to 86,400 seconds):

```sh
caas sandboxes exec build-agent <exec-id>
caas sandboxes exec build-agent <exec-id> --cancel
```

### With the API

```sh
curl https://api.caas.sh/v1/sandboxes/build-agent/exec \
  -H "Authorization: Bearer $CAAS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: run-tests-0001" \
  -d '{ "command": ["npm", "test"], "env": { "CI": "1" }, "timeoutSeconds": 1800 }'
```

The body takes `command`, and optionally `stdin` (text up to 64 KiB), `env`, `workdir`, `timeoutSeconds` (1 to 7,200; 600 by default) and `detach`. The `Idempotency-Key` becomes the exec's ID, and resending it never runs the command twice. The answer is `200` once the command ended, within about five minutes or its time limit, or `202` with its ID while it runs (at once with `"detach": true`):

```json
{ "execId": "run-tests-0001", "state": "succeeded", "detach": false, "createdAt": 1791797400000, "endedAt": 1791797412000,
  "exitCode": 0, "signal": null, "stdout": "…", "stderr": "", "stdoutTruncated": false }
```

`state` is `submitting`, `running`, `succeeded`, `failed`, `timed_out`, `canceled` or `lost`. `stdout` and `stderr` are `null` until it ends, then up to 1 MiB each (`stdoutTruncated` or `stderrTruncated` when cut). Read it again with `GET …/exec/<exec-id>`, and cancel it with `DELETE …/exec/<exec-id>`.

## Read the log

A sandbox's log holds what isolance recorded about it (its starts, stops and failures, as `system` lines) and each line its command wrote (`stdout` and `stderr`). The console shows it as **Runtime output** on the sandbox's page.

```sh
caas sandboxes logs build-agent
caas sandboxes logs build-agent --since 2026-10-11T09:00:00Z --follow
```

In the API, `GET /v1/sandboxes/<sandbox>/logs` answers the newest 1,000 entries at or after `?since=` (milliseconds or an ISO 8601 time), oldest first: `{ "entries": [{ "at", "stream", "message", "kind" }] }`. With `?follow=true`, the answer is newline-delimited JSON: those entries, then each new one as it comes, for up to 10 minutes; follow on with `since`. A command's output is also in its exec (see [Run commands](#run-commands)).

## Move files

The files API reads, writes and deletes paths in a sandbox, up to 100 MiB a file. A path is absolute, not under `/proc`, `/sys`, `/dev` or `/workspace/.caas` (which belongs to isolance). A transfer starts a sandbox that stopped while idle, and counts as activity.

### In the console

On the sandbox's page, the **Files** tab lists `/workspace`, folders first, with each entry's type and size. Open a folder to go into it, and go back up with the path above the list, as far as `/`. Open a text file to read it (up to 256 KB); **Download** saves any file. **Upload** puts files into the folder shown, **New folder** makes one, and each row's **⋯** menu has **Download** and **Delete** (a folder with everything in it). On a stopped sandbox, **Browse files** starts it. A transfer can take a minute or more per MB; the tab shows what it is doing and for how long, and waits until it's done. `?tab=files` in the page's address opens the tab.

### With the CLI and the API

```sh
caas sandboxes files put build-agent /workspace/config.json config.json
caas sandboxes files put build-agent /workspace/site site.tar.gz --extract
caas sandboxes files put build-agent /workspace --from .
caas sandboxes files get build-agent /workspace/config.json > config.json
caas sandboxes files get build-agent /workspace
caas sandboxes files delete build-agent /workspace/tmp --recursive
```

| Request | Does |
| --- | --- |
| `GET /v1/sandboxes/<sandbox>/files/<path>` | A file's bytes (`?tail=N` for its last N bytes), or a directory's listing: `{ "path", "entries": [{ "name", "type", "size" }] }` |
| `PUT …/files/<path>` | Writes the body as the file, creating its directories. With `?extract=true`, the body is a gzipped tar unpacked into the directory `<path>`. |
| `DELETE …/files/<path>` | Deletes the file; a directory needs `?recursive=true` |

Percent-encode each segment of the path, as in `…/files/workspace/my%20file.txt`. The bytes you read bill as egress. Only the sandbox's volumes are kept between restarts.

## Outbound access

A sandbox's `egress` lists the hosts it may reach:

- `*` allows every host. It's the default for a sandbox created without a list.
- A list of up to 32 hosts allows those hosts and blocks everything else. Write each as an exact host, such as `pypi.org`, or as `*.example.com` for the names under example.com (list `example.com` as well if the sandbox calls it). A host is never an IP address, a port, a path or `*` inside a list.
- An empty list reaches no host but its connectors' hosts.

The hosts of the [connectors](/docs/connectors) a sandbox gets are always allowed beside its list, and isolance adds their keys to its HTTPS requests there.

Where you set it:

- **Console:** in **New sandbox**, list the hosts under **Allowed outbound hosts**, one per line, or leave it empty for every host. On an existing sandbox, choose **Edit** on its **Network** card and change the list there. Deploying an MCP server has the same field, where an empty list reaches no host.
- **CLI:** pass `--egress HOST` once per host to `caas sandboxes create`, `caas sandboxes update`, `caas run` or `caas mcp create`; `--egress '*'` allows every host, and `--no-egress` none:

  ```sh
  caas run --egress api.github.com -- node -e "fetch('https://api.github.com/zen').then(r => r.text()).then(console.log)"
  ```

  For a command that starts with `npx`, the CLI adds `registry.npmjs.org` to a list that doesn't already cover it.

- **API:** `"egress": ["api.github.com", "*.npmjs.org"]` on `POST` or `PATCH /v1/sandboxes/<sandbox>`.
- **Files:** list hosts under `egress:` in an MCP server file.

A change between two lists applies to a running sandbox at once. A change between `*` and a list applies at its next start, and the sandbox's `pendingRestart` says so until then.

### What a list allows

- A sandbox with a list reaches its hosts over HTTP and HTTPS. With `*`, it reaches any host on any port.
- `registry.caas.sh` is always reachable, so a sandbox can pull images from your registry.
- A list never reaches an IP address, `localhost` or an internal name, and reaches only hosts under these top-level domains: .ai, .app, .au, .biz, .br, .ca, .cc, .ch, .cloud, .cn, .co, .com, .de, .dev, .edu, .es, .eu, .fr, .gg, .gov, .in, .info, .io, .it, .jp, .kr, .ly, .me, .net, .nl, .org, .page, .pl, .run, .se, .sh, .so, .tech, .tv, .uk, .us and .xyz.

Owners and operators can change a sandbox's outbound hosts; everyone in the workspace can read them. The bytes a sandbox on Native sends to the hosts it's allowed to reach bill as egress; see [pricing](/pricing.html).

## URLs

A sandbox's ports are served by its provider. While the sandbox runs, its `urls` list the provider's own URL for each port it lists, where the provider gives one. isolance doesn't sit in between: who can open a URL is up to the provider, which may answer only requests that carry its own credentials for the sandbox, and isolance never shows those. E2B and Daytona give each port a URL; on Native, Freestyle and Maritime a sandbox's `urls` are empty.

The first listed port, or 8080 when it lists none, is the one exposed. No variable is set for it: the sandbox's process listens on it itself.

Add, remove and change ports in the console's network page (**Edit** on the **Network** card), with `--port` in the CLI (`caas sandboxes update build-agent --port 3000 --port 9229`), or with `"ports": [{ "port": 3000 }, { "port": 9229 }]` on create or `PATCH`. A port's `public` (`--port 3000:public`, or **Public** in the console's **Details**) is kept with it, but isolance serves no URL of its own, so it opens nothing.

### What to know

- A request to a URL goes to the provider: it doesn't count as activity, doesn't start a stopped sandbox, and isolance doesn't bill it.
- `urls` are empty while the sandbox doesn't run.

## Snapshots

A snapshot is a saved copy of a sandbox's volumes, taken when you take one, with a name or called `manual`, and kept until you delete it.

The snapshot a sandbox that keeps state would start from if it lost its volumes is its recovery point, marked `current`. Snapshot storage bills per GB-month (see [pricing](/pricing.html)); taking and restoring snapshots is included.

### Take and list snapshots

Snapshots are taken of a running sandbox. Choose **Take snapshot** on the sandbox's page and enter a name or leave it empty, or:

```sh
caas sandboxes snapshots create build-agent --name before-upgrade
caas sandboxes snapshots list build-agent
```

In the API, `POST /v1/sandboxes/<sandbox>/snapshots` with an optional `{ "name": "before-upgrade" }`, and `GET …/snapshots`, which answers `{ "snapshots", "storedBytes" }`. A name follows the rules for [sandbox names](#names).

### Restore a snapshot

1. Stop the sandbox. Take a snapshot first if you want to come back to what you have now.
2. Choose **Restore** beside the snapshot on the sandbox's page, or run `caas sandboxes snapshots restore build-agent before-upgrade` (a snapshot's ID, or a manual snapshot's name). In the API, `POST /v1/sandboxes/<sandbox>/restore` with `{ "snapshot": "<id or name>" }`.

The sandbox starts with that snapshot as its volumes. Newer snapshots stay. If the snapshot can't start, the sandbox stays stopped with its previous recovery point.

### Delete a snapshot

Choose **Delete** beside the snapshot, run `caas sandboxes snapshots delete build-agent <snapshot-id>`, or send `DELETE …/snapshots/<snapshot-id>`. You can't delete the current recovery point of a sandbox that keeps state until a newer snapshot exists.

## Delete a sandbox

Choose **Delete** in the sandbox's row menu in **Sandboxes**, run `caas sandboxes delete <sandbox>`, or send `DELETE /v1/sandboxes/<sandbox>`. Deleting a sandbox removes its volumes, snapshots and logs for good, and frees its name. Deleting a sandbox that hosts an MCP server deletes the server too. Deleting one a workflow keeps between runs fails a step running in it; the workflow's next step on it creates it again.

## List sandboxes

The console's **Sandboxes** page lists every sandbox of the workspace, those hosting MCP servers too, with filters by state and a search by name, ID, image or label.

```sh
caas sandboxes list --label team=web --provider cloudflare
```

`GET /v1/sandboxes` answers `{ "sandboxes", "nextCursor" }`, newest first, 50 at a time (`?limit=` up to 100); pass `nextCursor` back as `?cursor=` for the next page. Filter with `?label=key=value` (repeat it; all must match; `caas.sh/user=<user>` finds a user's sandboxes) and `?provider=`.

## A web browser

With the [Browser](/docs/browser) connector, the AI tools in a sandbox it reaches get a web browser, as an MCP server named `browser` in their settings at every start. A sandbox started for a user signs in to websites with that user's [logins](/docs/logins), and one without a user with your workspace's; the AI never sees their passwords, codes or passkeys.

- Its browsers run outside the sandbox, so the sites they open needn't be among its outbound hosts, and they take nothing of its size.
- A file a browser tool reads or writes, such as an upload or a screenshot, is a file of this sandbox, relative to its working directory.
- Its browsers close when it stops or is deleted, and the next tool after a start opens a new one.
- Browser time bills apart from the sandbox's own (see [Browser time](/docs/browser#browser-time)).

## Limits

A workspace has no vCPU or memory quota: its balance is what bounds the sandboxes it runs. These are the limits per sandbox and per command.

| Limit | Value |
| --- | --- |
| Command | 1 to 32 arguments of up to 512 characters each |
| Command time limit | 1 second to 2 hours (24 hours detached) |
| Command output | 1 MiB per stream |
| Standard input | 64 KiB |
| Variables | 64, values up to 4,096 characters |
| Volumes | 8 |
| Ports | 16 |
| Outbound hosts | 32 |
| Connectors | 16 egress rules and 32 connector hosts per sandbox, logins' deliveries included; see [Connectors](/docs/connectors#limits) |
| Labels | 16 |
| File transfer | 100 MiB per file |
| Idle stop | 5 to 240 minutes |
