---
title: Start warm workers from a snapshot
sidebarTitle: Warm workers
description: Install a toolchain once and launch clean workers from the captured disk state
icon: "code-branch"
---

<Tooltip tip="This workflow uses local snapshot verification and destination security controls."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

Package installation often costs more than sandbox boot. This example installs OpenCode once, records the stopped sandbox as an integrity-checked snapshot, and launches fresh workers from that prepared filesystem.

## Start a warm worker

<Steps>

<Step title="Prepare the baseline">

Create the worker verification script that the snapshot will carry into every worker:

```sh verify-worker.sh
#!/bin/sh
set -eu

test "$(id -u)" -ne 0
git init -q
git add .
git -c user.name=microsandbox \
  -c user.email=worker@microsandbox.local \
  commit -qm "sandbox baseline"
test -z "$(git remote)"
opencode --version
```

Create the preparation script that installs the baseline toolchain:

```sh prepare-worker.sh
#!/bin/sh
set -eu

apt-get update
apt-get install -y --no-install-recommends ca-certificates git
rm -rf /var/lib/apt/lists/*
npm install -g opencode-ai@1.18.4
mkdir -p /workspace/project
chown -R node:node /workspace
opencode --version
```

<CodeGroup>
```sh macOS & Linux
msb run --name agent-base --replace \
  --cpus 2 --memory 2G --root-disk 4G \
  --script-path prepare-worker:./prepare-worker.sh \
  --script-path verify-worker:./verify-worker.sh \
  --entrypoint prepare-worker \
  node:24-bookworm-slim
```

```powershell Windows
msb run --name agent-base --replace `
  --cpus 2 --memory 2G --root-disk 4G `
  --script-path prepare-worker:./prepare-worker.sh `
  --script-path verify-worker:./verify-worker.sh `
  --entrypoint prepare-worker `
  node:24-bookworm-slim
```
</CodeGroup>

When the command exits, `agent-base` is stopped and ready to snapshot.

</Step>

<Step title="Create and verify the snapshot">

<CodeGroup>
```sh macOS & Linux
msb snapshot create coding-agent-base \
  --from-sandbox agent-base \
  --integrity
```

```powershell Windows
msb snapshot create coding-agent-base `
  --from-sandbox agent-base `
  --integrity
```
</CodeGroup>

Verify the captured snapshot before using it:

```sh
msb snapshot verify agent-base:coding-agent-base
```

The snapshot captures the writable disk changes and pins the source image. This disk snapshot does not capture memory, running processes, network state, or environment variables. Owned storage is captured; external directory bindings require explicit destination choices. Integrity verification detects later changes to those captured bytes; it does not attest who built the snapshot or whether its packages are trustworthy.

<Warning>
  Snapshots preserve every file written to the guest disk, including shell history, tool configuration, and cached credentials. Build the baseline in a trusted workflow, and never authenticate OpenCode or place registry tokens, source code, or API keys in `agent-base`.
</Warning>

</Step>

<Step title="Launch a clean worker">

Restore creates an idle detached sandbox with its security, resource, and lifetime controls applied before boot. It requires an unused name; remove a previous stopped worker explicitly before reusing that name. Start each workload separately with `msb exec`.

<CodeGroup>
```sh macOS & Linux
msb restore agent-base:coding-agent-base --name coding-worker-1 \
  --cpus 2 --memory 2G \
  --user node --security restricted --max-duration 1h
```

```powershell Windows
msb restore agent-base:coding-agent-base --name coding-worker-1 `
  --cpus 2 --memory 2G `
  --user node --security restricted --max-duration 1h
```
</CodeGroup>

Transfer the committed project tree into the worker:

<CodeGroup>
```sh macOS & Linux
git -C ./my-project archive --format=tar HEAD | \
  msb exec --stream --user node \
    --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 \
    coding-worker-1 -- tar -x -C /workspace/project
```

```powershell Windows
git -C ./my-project archive --format=tar --output=project.tar HEAD
msb cp ./project.tar coding-worker-1:/tmp/project.tar
msb exec --user node `
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 `
  coding-worker-1 -- tar -x -f /tmp/project.tar -C /workspace/project
Remove-Item ./project.tar
```
</CodeGroup>

Create a credential-free Git baseline and verify the worker boundary:

<CodeGroup>
```sh macOS & Linux
msb exec --user node --workdir /workspace/project \
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 \
  coding-worker-1 -- verify-worker
```

```powershell Windows
msb exec --user node --workdir /workspace/project `
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 `
  coding-worker-1 -- verify-worker
```
</CodeGroup>

Start OpenCode after those checks pass:

<CodeGroup>
```sh macOS & Linux
msb exec -t --user node --workdir /workspace/project \
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 \
  coding-worker-1 -- opencode
```

```powershell Windows
msb exec -t --user node --workdir /workspace/project `
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 `
  coding-worker-1 -- opencode
```
</CodeGroup>

Dedicated restore does not accept rootfs patches such as `--copy-dir`, so the worker boots first and receives the committed tree afterward. `git archive` excludes `.git`, checkout credentials, and untracked files such as a local `.env`; review the committed tree for secrets before sending it. Initializing a new repository inside the worker preserves useful diff workflows without copying host remotes or credentials. Each transferred or interactive workload sets its own process, file-descriptor, and per-file limits.

Each launch receives its own writable layer. Changes made by one worker do not modify the snapshot, the host project, or another worker.

<Note>
  This worker uses microsandbox's default public-internet profile so OpenCode can reach a configured provider. For sensitive projects, replace it with a deny-by-default allowlist for the provider and source hosts you need, and use [host-held secrets](/sandboxes/secrets) instead of copying credentials into the worker.
</Note>

Create more workers by changing the sandbox name:

<CodeGroup>
```sh macOS & Linux
msb restore agent-base:coding-agent-base --name coding-worker-2 \
  --user node --security restricted --max-duration 1m
msb exec --user node --timeout 1m \
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 \
  coding-worker-2 -- opencode --version
msb stop coding-worker-2
```

```powershell Windows
msb restore agent-base:coding-agent-base --name coding-worker-2 `
  --user node --security restricted --max-duration 1m
msb exec --user node --timeout 1m `
  --rlimit nproc=256 --rlimit nofile=1024 --rlimit fsize=268435456 `
  coding-worker-2 -- opencode --version
msb stop coding-worker-2
```
</CodeGroup>

</Step>

<Step title="Clean up">

Remove the prepared sandbox and workers:

<CodeGroup>
```sh macOS & Linux
msb rm -f agent-base coding-worker-1 coding-worker-2
rm -f prepare-worker.sh verify-worker.sh
```

```powershell Windows
msb rm -f agent-base coding-worker-1 coding-worker-2
Remove-Item prepare-worker.sh, verify-worker.sh
```
</CodeGroup>

Remove the reusable snapshot only when you no longer need it:

```sh
msb snapshot rm agent-base:coding-agent-base
```

</Step>

</Steps>

## Refresh the baseline

Installed snapshot members are immutable. To update packages, recreate `agent-base`, then capture a new member name and use its group-qualified selector for future workers:

```sh
msb snapshot create coding-agent-base-v2 --from-sandbox agent-base --integrity
msb snapshot verify agent-base:coding-agent-base-v2
```

See [Snapshots](/sandboxes/snapshots) for archive, integrity, and portability details.
