# How do I give each of my users their own persistent agent computer?

> Create one template for your product and one Sanbox Computer per user, keyed by your user ID. Stop it when they leave, resume it when they return, and use warm pools for fast first starts.

- Source: Sanbox knowledge base, by Sanlabs GmbH
- URL: https://sanbox.cloud/kb/build/one-persistent-computer-per-user/
- Type: how-to
- Section: Building agent products
- Language: en
- Published: 2026-11-06
- Updated: 2026-11-06

Keep one long-lived computer per user and stop it between sessions, instead of building a fresh sandbox every time. With Sanbox, your backend creates a Computer from your product's template using your user's ID as `--external-run-id`, stops it when the user goes idle and resumes it when they come back, with their files, installed packages and the agent's saved state still on its disk. Snapshots and warm pools make first starts fast, and Secret Proxies keep your API keys out of every Computer.

## Run this with your agent

```text
Read https://sanbox.cloud/kb/build/one-persistent-computer-per-user.md and follow it to set up one Computer per user for my app.
If the Sanbox CLI is missing, install it with `npm install -g @sanlabs/sanbox-cli@latest`
and sign in with `sanbox login`. Show me each command before you create, stop or delete a Computer.
```

## What does the architecture look like?

| In your product | In Sanbox |
|---|---|
| The product, or one environment of it | One template: agent, model, network policy, Secret Proxies |
| An end user | One Computer, created with `--external-run-id "user-<user-id>"` |
| The user is active | The Computer is running |
| The user is away | The Computer is stopped: its disk is saved, its compute ends |
| Your backend talks to the agent | A short-lived OpenCode SDK connection |
| A prepared starting state | A snapshot template with a warm pool |

Your backend calls the Sanbox CLI or API with an organisation API key in `SANBOX_API_KEY`. Your users never see that key. The same pattern suits features where each end user gets their own agent, working in its own Computer.

## Steps

### 1. Create the product template

An organisation admin creates it once, with the network policy and Secret Proxies every user's Computer should get:

```bash
sanbox templates create --name "Product agent" --type opencode-computer \
  --model-provider <provider-id> --model <model-id> \
  --network-policy policy.json --secret-proxy <proxy-name> --json
sanbox templates validate <template-id> --json
```

### 2. Create a Computer the first time a user needs one

```bash
sanbox run --template <template-id> --external-run-id "user-<user-id>" --json
```

Store the returned run ID with the user's record. If the request times out, repeat it with the same external ID: Sanbox returns the existing Computer instead of creating a second one. Poll `sanbox runs get <run-id> --json` until the run is `running`. Don't use `--wait` here; it waits for the Computer to stop.

### 3. Connect your backend to the agent

```bash
sanbox opencode connect <run-id> --expires 1h --json
```

The response holds `data.url` and a one-time `data.access_token`. Pass them to the native OpenCode SDK (`@opencode-ai/sdk`) as the base URL and a bearer token, then create sessions, send prompts and stream events to your user. Keep the token on your server. It stops working when it expires, is revoked, or the Computer restarts, so create a new connection after every resume. Never give `SANBOX_API_KEY` to the SDK.

### 4. Stop the Computer when the user goes idle

```bash
sanbox runs stop <run-id> --json
```

Stop is asynchronous, so check `sanbox runs get` until `state` is `stopped`. OpenCode Computers stay on until they're stopped. Sanbox doesn't stop or wake them on its own, so your app decides what idle means.

### 5. Resume it when the user returns

```bash
sanbox runs resume <run-id> --wait --json
```

Resume boots the pinned runtime fresh with the saved disk, and reuses the model the Computer started with. Then create a new connection, as in step 3.

### 6. Delete it when the user leaves your product

```bash
sanbox runs delete <run-id> --yes --json
```

Delete permanently removes the saved disk.

## Make first starts fast

Do the slow setup once. Prepare one Computer with your tools and files, stop it, and capture it (this needs an organisation admin or owner). Then build a template on the snapshot and keep ready Computers in a pool:

```bash
sanbox snapshots create --run <stopped-run-id> --name product-base
sanbox templates create --name "Product agent" --snapshot product-base \
  --model-provider <provider-id> --network-policy policy.json --json
sanbox pools create --template <template-id> --name product-pool --size 3
```

`sanbox run --template <template-id> --external-run-id "user-<user-id>" --json` now takes a ready Computer when the pool has one, and starts one cold when it doesn't. A pool keeps at most five ready Computers, and they use ordinary capacity. Runs from a snapshot template take no task or model override. When you improve the base, `sanbox templates update <template-id> --snapshot <new-snapshot>` promotes it, and the pool's unused Computers are replaced. See [how to make agent computers start instantly](https://sanbox.cloud/kb/build/warm-pools-and-snapshot-templates/).

## Lock down egress

Each template's network policy is deny-by-default and covers every Computer built from it. Allow only the hosts your agent needs:

```json
{
  "default_action": "deny",
  "rules": [{ "destination": "api.example.com", "ports": [{ "from": 443, "to": 443 }] }]
}
```

For your own API, use a Secret Proxy instead of putting a key in the Computer. Sanbox adds the credential to matching HTTPS requests on their way out, so the agent calls the original URL and never sees the key. With `"attach_run_id": true` in the proxy's settings, requests also carry the run ID in `X-Sanbox-Run-ID`, which lets your API tell which user's Computer is calling. Your API must still authenticate the integration first, because the run ID isn't a credential.

If your users sign in with Supabase, a Computer can read their data under your RLS policies. See [Supabase users with a persistent agent computer](https://sanbox.cloud/kb/build/supabase-users-get-a-computer/).

## Which plan fits?

Sanbox is priced per organisation. Enterprise plans add professional services for custom integrations and deployment in your VPCs, and our [forward-deployed engineers](https://sanbox.cloud/kb/teams/forward-deployed-engineering/) can build the integration into your product with you. [Talk to us](mailto:sales@sanlabs.ai) about the number of Computers you need.

## What this doesn't do

- **No automatic idle stop or wake.** Your backend calls stop and resume.
- **No memory across a stop.** RAM and running processes end. Resume boots fresh from the saved disk.
- **Retry a failed resume.** If a resume fails, retry it later. Don't create a new run to take over the same disk.
- **Disks are 1 to 8 GB.** That holds `/workspace` and every installed package.
- **Your backend controls access for end users.** Your users reach their Computers only through your product. Members of your Sanbox organisation with operator roles can work on its Computers, so give those roles only to people who run your service.

## Related

- [How do I make agent computers start instantly?](https://sanbox.cloud/kb/build/warm-pools-and-snapshot-templates/)
- [How do I give Supabase users a persistent agent computer that respects RLS?](https://sanbox.cloud/kb/build/supabase-users-get-a-computer/)
- [How do I use my own model endpoint with an agent computer?](https://sanbox.cloud/kb/build/bring-your-own-model-endpoint/)
- [How do I give an AI agent API keys without exposing them?](https://sanbox.cloud/kb/security/api-keys-your-agent-cannot-see/)
- [What survives when an agent's computer stops?](https://sanbox.cloud/kb/agent-computers/what-survives-a-stop/)

## Next step

Talk to us at sales@sanlabs.ai. Sanlabs' forward-deployed engineers build agent use cases with your team, with experience in aviation, pharmaceuticals, supply chain and logistics, and internal admin workflows. How we work: https://sanbox.cloud/kb/teams/forward-deployed-engineering.md

Existing customers can use Sanbox from a coding agent: install the CLI with `npm install -g @sanlabs/sanbox-cli@latest`, sign in with `sanbox login`, then run `sanbox skill` for the full agent guide.
