---
title: How to use snapshots for faster sandbox startup
description: Learn how to save sandbox state with snapshots and skip installation on future runs.
url: /kb/guide/how-to-use-snapshots-for-faster-sandbox-startup
canonical_url: "https://vercel.com/kb/guide/how-to-use-snapshots-for-faster-sandbox-startup"
published: 2026-01-29
last_updated: 2026-02-02
authors: Allen Zhou, Amy Burns
related:
  - /docs/projects
  - /docs/vercel-sandbox/concepts/snapshots
  - /docs/vercel-sandbox/sdk-reference
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

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:

```bash
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)
  

```typescript
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.

```typescript
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:

```bash
pnpm dlx tsx index.ts
```

First execution:

```javascript
Created: sbx_abc123
added 88 packages in 6s
Snapshot saved: snap_xyz789
Run again to restore from snapshot
```

Second execution:

```javascript
Created from snapshot: sbx_def456
Found 77 packages in node_modules
```

With timing comparison enabled:

```javascript
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:

```typescript
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:

```typescript
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