How to reconnect to a running Sandbox

Learn how to use Sandbox.get() to reconnect to an existing sandbox from a different process or after a script restart.

3 min read
Last updated February 2, 2026

When you create a sandbox, it continues running until it times out or you explicitly stop it. If your script crashes, your connection drops, or you need to interact with the sandbox from a different process, you can reconnect using Sandbox.get().

This is different from snapshots, which save the sandbox state for later restoration. Sandbox.get() connects to a sandbox that is actively running.

You need the Vercel CLI, Node.js 22+, and a Vercel project to link your sandbox and generate an OIDC token.

mkdir sandbox-reconnect-demo && cd sandbox-reconnect-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.

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

  • Phase 1: Create a sandbox, persist its ID to disk, and exit
  • Phase 2: Load the ID, call Sandbox.get() to reconnect
import { config } from 'dotenv';
config({ path: '.env.local' });
import { Sandbox } from '@vercel/sandbox';
import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs';
const ID_FILE = './sandbox-id.txt';
async function main() {
if (existsSync(ID_FILE)) {
const id = readFileSync(ID_FILE, 'utf-8').trim();
try {
const sandbox = await Sandbox.get({ sandboxId: id });
console.log(`Reconnected to ${sandbox.sandboxId}`);
// Do work here...
await sandbox.stop();
unlinkSync(ID_FILE);
} catch {
unlinkSync(ID_FILE);
await createSandbox();
}
} else {
await createSandbox();
}
}
async function createSandbox() {
const sandbox = await Sandbox.create({ timeout: 10 * 60 * 1000 });
writeFileSync(ID_FILE, sandbox.sandboxId);
console.log(`Created ${sandbox.sandboxId}, run again to reconnect`);
}
main().catch(console.error);

To measure the speedup from reconnecting vs cold start:

import { config } from 'dotenv';
config({ path: '.env.local' });
import { Sandbox } from '@vercel/sandbox';
import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs';
const ID_FILE = './sandbox-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);
const rm = (f: string) => existsSync(f) && unlinkSync(f);
async function main() {
if (existsSync(ID_FILE)) {
const id = read(ID_FILE);
const coldMs = existsSync(TIME_FILE) ? +read(TIME_FILE) : null;
try {
const start = Date.now();
const sandbox = await Sandbox.get({ sandboxId: id });
const reconnectMs = Date.now() - start;
console.log(`Reconnected in ${(reconnectMs / 1000).toFixed(2)}s`);
if (coldMs) {
console.log(`Cold: ${(coldMs / 1000).toFixed(2)}s → ` +
`${(coldMs / reconnectMs).toFixed(1)}x faster`);
}
await sandbox.stop();
} catch {
console.log('Sandbox expired, creating new...');
}
rm(ID_FILE);
rm(TIME_FILE);
} else {
const start = Date.now();
const sandbox = await Sandbox.create({ timeout: 10 * 60 * 1000 });
write(ID_FILE, sandbox.sandboxId);
write(TIME_FILE, String(Date.now() - start));
console.log(`Created ${sandbox.sandboxId}, run again to reconnect`);
}
}
main().catch(console.error);

Execute the script twice in quick succession:

pnpm dlx tsx index.ts

First execution:

Created sbx_abc123, run again to reconnect

Second execution (before the 10-minute timeout):

Reconnected in 0.31s
Cold: 2.34s → 7.5x faster
  • Script recovery: Reconnect after a crash without losing your running environment
  • Multi-process workflows: Access the same sandbox from different scripts or terminals
  • CLI tools: Separate sandbox lifecycle management from command execution
  • Interactive development: Keep a sandbox warm between debugging sessions

If the sandbox timed out or was stopped, Sandbox.get() throws an error. Always wrap it in a try-catch:

try {
const sandbox = await Sandbox.get({ sandboxId });
console.log('Reconnected successfully');
} catch (error) {
console.log('Sandbox no longer available, creating a new one...');
const sandbox = await Sandbox.create({ runtime: 'node22' });
}
OperationTypical Time
Create new sandbox~2-3s
Reconnect with Sandbox.get()~0.3s

The ~10x speedup makes Sandbox.get() ideal for keeping sandboxes warm between commands.

Sandbox.get()Snapshot.get()
TargetRunning sandboxSaved state
RequirementSandbox must be activeSandbox can be stopped
PersistenceUntil timeout7 days
Best forInteractive sessionsReusable templates

Was this helpful?

supported.