# How to use snapshots for faster sandbox startup

**Author:** Allen Zhou, Amy Burns

---

Every time you create a new sandbox, you start with a fresh environment. If your setup involves installing dependencies, cloning repositories, or building code, it can take a while. Snapshots let you save that configured state and create new sandboxes from it, skipping the setup entirely.

With snapshots, you:

1. Set up your environment once (install dependencies, configure tools)
   
2. Save the configured state as a snapshot
   
3. Launch future sandboxes from that snapshot with everything already in place
   

Snapshots persist across sessions, so you can reuse them without repeating setup.

## Prerequisites

Before you begin, make sure you have:

- Vercel CLI installed (`npm install -g vercel`)
  
- Node.js 22 or later
  
- A [Vercel project](https://vercel.com/docs/projects) to link your sandbox and generate an OIDC token
  

## 1\. Project setup

Create a new directory and install dependencies:

`mkdir sandbox-snapshot-demo cd sandbox-snapshot-demo pnpm init pnpm add @vercel/sandbox dotenv pnpm add -D @types/node vercel link vercel env pull`

This installs the SDK, links to your Vercel project, and creates `.env.local` with authentication credentials.

## 2\. Write the script

Create `index.ts` with the code below. It runs in two modes:

- First run: Create sandbox, install dependencies, take snapshot
  
- Second run: Create sandbox from snapshot (deps already there)
  

``import { config } from 'dotenv'; config({ path: '.env.local' }); import { Sandbox, Snapshot } from '@vercel/sandbox'; import { writeFileSync, readFileSync, existsSync } from 'fs'; const ID_FILE = './snapshot-id.txt'; async function main() { if (existsSync(ID_FILE)) { const snapshotId = readFileSync(ID_FILE, 'utf-8').trim(); const snapshot = await Snapshot.get({ snapshotId }); const sandbox = await Sandbox.create({ source: { type: 'snapshot', snapshotId: snapshot.snapshotId }, timeout: 10 * 60 * 1000, }); console.log(`Created from snapshot: ${sandbox.sandboxId}`); // Verify deps are pre-installed const result = await sandbox.runCommand({ cmd: 'ls', args: ['node_modules'] }); const count = (await result.stdout()).split('\n').filter(Boolean).length; console.log(`Found ${count} packages in node_modules`); await sandbox.stop(); } else { await createAndSnapshot(); } } async function createAndSnapshot() { const sandbox = await Sandbox.create({ timeout: 10 * 60 * 1000 }); console.log(`Created: ${sandbox.sandboxId}`); const deps = ['typescript', 'eslint', 'prettier', 'zod']; await sandbox.runCommand({ cmd: 'npm', args: ['install', ...deps], stdout: process.stdout, stderr: process.stderr, }); const snapshot = await sandbox.snapshot(); writeFileSync(ID_FILE, snapshot.snapshotId); console.log(`Snapshot saved: ${snapshot.snapshotId}`); console.log('Run again to restore from snapshot'); } main().catch(console.error);`` ### With timing comparison To measure the speedup you get from snapshots, use the below version. It records the cold-start time on the first run, then prints the warm-start time (and savings) on the second run. ``import { config } from 'dotenv'; config({ path: '.env.local' }); import { Sandbox, Snapshot } from '@vercel/sandbox'; import { writeFileSync, readFileSync, existsSync } from 'fs'; const ID_FILE = './snapshot-id.txt'; const TIME_FILE = './cold-start.txt'; const read = (f: string) => readFileSync(f, 'utf-8').trim(); const write = (f: string, v: string) => writeFileSync(f, v); async function main() { if (existsSync(ID_FILE)) { const snapshotId = read(ID_FILE); const coldMs = existsSync(TIME_FILE) ? +read(TIME_FILE) : null; const snapshot = await Snapshot.get({ snapshotId }); const start = Date.now(); const sandbox = await Sandbox.create({ source: { type: 'snapshot', snapshotId: snapshot.snapshotId }, timeout: 10 * 60 * 1000, }); const warmMs = Date.now() - start; console.log(`Warm start: ${(warmMs / 1000).toFixed(2)}s`); if (coldMs) { console.log(`Cold start: ${(coldMs / 1000).toFixed(2)}s → ` + `saved ${((coldMs - warmMs) / 1000).toFixed(1)}s`); } await sandbox.stop(); } else { const start = Date.now(); const sandbox = await Sandbox.create({ timeout: 10 * 60 * 1000 }); const deps = ['typescript', 'eslint', 'prettier', 'zod']; await sandbox.runCommand({ cmd: 'npm', args: ['install', ...deps], stdout: process.stdout, stderr: process.stderr, }); const snapshot = await sandbox.snapshot(); write(ID_FILE, snapshot.snapshotId); write(TIME_FILE, String(Date.now() - start)); console.log(`Snapshot saved, run again to restore`); } } main().catch(console.error);`` ## 3\. Test it out Execute the script twice: `pnpm dlx tsx index.ts` First execution: `Created: sbx_abc123 added 88 packages in 6s Snapshot saved: snap_xyz789 Run again to restore from snapshot` Second execution: `Created from snapshot: sbx_def456 Found 77 packages in node_modules` With timing comparison enabled: `Warm start: 0.41s Cold start: 16.49s → saved 16.1s` ## Key concepts ### Taking a snapshot Call `snapshot()` on a running sandbox to save its state: `const snapshot = await sandbox.snapshot(); console.log(snapshot.snapshotId); // snap_abc123` **Important:** The sandbox stops automatically after snapshotting. You cannot run more commands on it. ### Creating a sandbox from a snapshot Pass the snapshot ID as the source when creating a new sandbox: `const sandbox = await Sandbox.create({ source: { type: 'snapshot', snapshotId: snapshot.snapshotId }, timeout: 10 * 60 * 1000, });` ### Snapshot lifecycle - You can create multiple sandboxes from the same snapshot    - Deleting a snapshot does not affect sandboxes already created from it    For more details, see the [Snapshotting documentation](https://vercel.com/docs/vercel-sandbox/concepts/snapshots).

## When to use snapshots vs Sandbox.get()

| Scenario                           | Use             |
| ---------------------------------- | --------------- |
| Keep sandbox warm between commands | `Sandbox.get()` |
| Reuse setup across sessions/days   | Snapshot        |
| Share environment with teammates   | Snapshot        |
| Survive sandbox timeout            | Snapshot        |
| Fastest possible reconnect         | `Sandbox.get()` |

## Next steps

- Learn about [Sandbox.get()](https://vercel.com/docs/vercel-sandbox/sdk-reference#sandbox.get) for reconnecting to running sandboxes
  
- See the [Sandbox SDK reference](https://vercel.com/docs/vercel-sandbox/sdk-reference) for all available methods

---

[View full KB sitemap](/kb/sitemap.md)
