> ## Documentation Index
> Fetch the complete documentation index at: https://docs.archil.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Create long-running Linux VMs with persistent disks, interactive shells, services, and forks.

Archil's persistent sandboxes make it simple to create long-running machines that simplify access to your Archil disk.
They are ideal for starting network services (such as web hosting, git hosting, or databases), interactive development
environments, or running untrusted AI-generated code for longer than an individual bash tool.

Persistent sandboxes can run for as long as you need without limit, and can be forked so you can run multiple copies of
the same sandbox in parallel. Persistent sandboxes are built on full-featured Linux microVMs that are colocated with your
Archil disk data for maximum security and performance.

If you instead need the ability to run one-off bash, Python, or Node code against your Archil disk, consider using
[serverless execution](/compute/serverless-execution) instead.

<Note>
  Persistent sandboxes are available in preview in Archil's AWS regions. During the preview period,
  sandboxes may be pre-empted, occasionally causing them to stop.
</Note>

You can easily create a persistent sandbox using the TypeScript SDK:

```typescript theme={null}
import * as archil from "disk";

const sandbox = await archil.createSandbox({
  // Sandbox name, for finding later
  name: "agent-workspace",

  // Supports public OCI images
  baseImage: "python:3.13",

  // Select the amount of vCPU and memory
  vcpuCount: 2,
  memSizeMiB: 4096,
});

const execution = await sandbox.processes.start("python --version && pwd");
const result = await execution.wait();
console.log(result.stdout);
```

Archil sandboxes are ARM-based and support between 1 and 32 vCPU cores and between 0.25 and 64 GiB of memory. Sandboxes run as the root
Linux user (uid: 0, gid: 0).

## Attaching an Archil disk

You can attach an Archil disk to a sandbox by using the usual command to mount the disk:

```typescript theme={null}
// First, install the Archil CLI to your image
const install = await sandbox.processes.start("curl https://archil.com/install | sh");
await install.wait();

// Then mount the file system
const mount = await sandbox.processes.start("mkdir /mnt/archil; archil mount dsk-1234 /mnt/archil", {
  env: {
    ARCHIL_MOUNT_TOKEN: "<token>",
  }
});
await mount.wait();
```

## Passing environment variables

Environment variables can be set for the whole sandbox, for a single command, or both. Variables passed when the
sandbox is created apply to every command that runs inside it:

```typescript theme={null}
const sandbox = await archil.createSandbox({
  baseImage: "python:3.13",
  env: {
    DATABASE_URL: "postgres://localhost/app",
    LOG_LEVEL: "info",
  },
});
```

Individual processes can add or override their own variables by passing `env` to `processes.start`:

```typescript theme={null}
// Runs with DATABASE_URL from the sandbox, and LOG_LEVEL=debug
const migration = await sandbox.processes.start("python manage.py migrate", {
  env: { LOG_LEVEL: "debug" },
});
await migration.wait();
```

## Starting and stopping sandboxes

A sandbox runs until you shut it down or its [TTL](#setting-a-time-to-live) expires. There are two ways to suspend one,
and they differ in how much state they keep.

Stopping a sandbox sends `SIGTERM` to every running process and shuts down the VM, leaving the disk intact:

```typescript theme={null}
await sandbox.stop();
```

Starting it again boots a fresh VM from that same disk:

```typescript theme={null}
await sandbox.start();
```

Everything written to disk survives, but memory does not, so your application handles shutdown and startup the same way
it would on any machine. You can instead pause a VM to snapshot memory alongside the disk, so a resumed sandbox
picks up exactly where it left off, with running processes intact:

```typescript theme={null}
// Stop the sandbox from incurring charges, keeping running application state intact
await sandbox.pause();

// Resume the sandbox from the paused state
await sandbox.resume();
```

Deleting a sandbox releases all of its resources and cannot be undone. A sandbox has to be stopped before it can be
deleted, unless it has already exited or failed:

```typescript theme={null}
await sandbox.stop();
await sandbox.delete();
```

## Forking a sandbox

In some situations, you may want to fork a sandbox into multiple branches from a single point in time. This makes it simple to,
for example, start sandboxes from a template without needing to incur startup latency for a slow-running program or run parallel
experiments on sandbox state from some point in the past.

You can fork a running or paused sandbox by calling:

```typescript theme={null}
const newSandbox = await sandbox.fork();
```

After forking, `newSandbox` will be able to run commands independently of the original sandbox, starting from the exact state
of the original sandbox.

During the preview period, all child sandboxes forked from a parent must be deleted before the parent sandbox is deleted.

## Hosting network services

Archil sandboxes support the ability to host network services, including creating per-sandbox preview URLs for CI-like
workflows.

You can create a network service by calling `archil-sandbox services create` from within a sandbox.

```typescript theme={null}
const serviceProcess = await sandbox.processes.start(
  "archil-sandbox services create web --tcp-port <port> -- <server run command>",
);
const { stdout } = await serviceProcess.wait();

const service = JSON.parse(stdout);
console.log("Server available at: ", service.hostname);
```

For example, the following code will create a network service with a stable HTTPS URL. When network traffic hits the
returned URL, the sandbox will automatically run `python3 -m http.server 8080` and proxy traffic to local port 8080.

```bash theme={null}
$ archil-sandbox services create web --tcp-port 8080 -- python3 -m http.server 8080
{
  "after": [],
  "command": ["python3", "-m", "http.server", "8080"],
  "enabled": true,
  "env": {},
  "hostname": "8080-<redacted>.prod-aws-us-west-2-green.archil.app",
  "name": "web",
  "state": {
    "exit_status": null,
    "pid": null,
    "restart_count": 0,
    "result": null,
    "status": "activating"
  },
  "tcp_port": 8080,
  "working_dir": null
}
```

Archil network services will automatically start sandboxes when network traffic is detected if the sandbox has been
stopped or killed by its TTL, and all Archil network services are served over a TLS connection.

<Warning>
  Sandbox network services are publicly accessible. Your service needs to include authentication/authorization if you
  want to expose a private service.
</Warning>

## Choosing a base image

Archil sandboxes can start with any public Linux OCI image, including Docker Hub shorthand like `python:3.13`
or full custom image references like `ghcr.io/acme/agent-runtime:v2`. Private registry images are not supported yet.
If you need private image support, please [contact us](mailto:support@archil.com).

The first time each user starts a sandbox with an OCI image, Archil performs a transformation process to convert this image
into a high-performance format that can be used to quickly start new sandboxes. This transformation only occurs once for
the lifecycle of your Archil account.

## Setting a time to live

During sandbox creation, you can optionally specify a TTL for that sandbox's run between 60 and 28,800 seconds (8 hours). By default,
sandboxes are created with a TTL of 8 hours. After this period of time, the sandbox will automatically shut down. During
the preview period, sandbox activity does not extend the initial TTL.

Restarting a sandbox after its TTL expires will also restart the TTL.

## Opening interactive shells

By default, processes run without allocating a pseudo-terminal (pty). This is usually desirable, since it signals
to the process that it is not in an interactive terminal. However, some commands, such as those that emit color, full-screen
tools like `vim` and `top`, or tools that need interactive input should instead be launched in a pseudo-terminal.

Provide terminal dimensions to launch a process in a pseudo-terminal. The process can then interactively receive input
and stream output to the caller:

```typescript theme={null}
const shell = await sandbox.processes.start("/bin/sh", {
  terminal: { cols: 120, rows: 40 },
  onOutput: ({ data }) => process.stdout.write(data),
});

await shell.sendInput("ls -la\n");
await shell.closeStdin();
const { exitCode } = await shell.wait();
```

## Next steps

* [TypeScript SDK](/sdks/typescript#persistent-sandboxes)
* [Create a sandbox](/api-reference/sandboxes/create-sandbox)
* [Create a process connection](/api-reference/sandboxes/create-sandbox-connection)
* [Fork a sandbox](/api-reference/sandboxes/fork-sandbox)
* [Sandbox lifecycle endpoints](/api-reference/sandboxes/pause-sandbox)
