Skip to content
Cloudflare Docs

Session management

Sessions are bash shell execution contexts within a sandbox. Think of them like terminal tabs or panes in the same container.

  • Sandbox = A computer (container)
  • Session = A terminal shell session in that computer

Default session

Every sandbox has a default session that maintains shell state between commands while the container is active:

TypeScript
const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
// These commands run in the default session
await sandbox.exec("cd /app");
await sandbox.exec("pwd"); // Output: /app
await sandbox.exec("export MY_VAR=hello");
await sandbox.exec("echo $MY_VAR"); // Output: hello

Working directory, environment variables, and exported variables carry over between commands. This state resets if the container restarts due to inactivity.

Creating sessions

Create additional sessions for isolated shell contexts:

TypeScript
const buildSession = await sandbox.createSession({
name: "build",
env: { NODE_ENV: "production" },
cwd: "/build"
});
const testSession = await sandbox.createSession({
name: "test",
env: { NODE_ENV: "test" },
cwd: "/test"
});
// Different shell contexts
await buildSession.exec("npm run build");
await testSession.exec("npm test");

What's isolated per session

Each session has its own:

Shell environment:

TypeScript
await session1.exec("export MY_VAR=hello");
await session2.exec("echo $MY_VAR"); // Empty - different shell

Working directory:

TypeScript
await session1.exec("cd /workspace/project1");
await session2.exec("pwd"); // Different working directory

Environment variables (set via createSession options):

TypeScript
const session1 = await sandbox.createSession({
env: { API_KEY: 'key-1' }
});
const session2 = await sandbox.createSession({
env: { API_KEY: 'key-2' }
});

What's shared

All sessions in a sandbox share:

Filesystem:

TypeScript
await session1.writeFile('/workspace/file.txt', 'data');
await session2.readFile('/workspace/file.txt'); // Can read it

Processes:

TypeScript
await session1.startProcess('node server.js');
await session2.listProcesses(); // Sees the server

Ports:

TypeScript
await session1.exposePort(3000);
await session2.getExposedPorts(); // Sees port 3000

When to use sessions

Use sessions when:

  • You need isolated shell state for different tasks
  • Running parallel operations with different environments
  • Keeping AI agent credentials separate from app runtime

Example - separate dev and runtime environments:

TypeScript
// Phase 1: AI agent writes code (with API keys)
const devSession = await sandbox.createSession({
name: "dev",
env: { ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY }
});
await devSession.exec('ai-tool "build a web server"');
// Phase 2: Run the code (without API keys)
const appSession = await sandbox.createSession({
name: "app",
env: { PORT: "3000" }
});
await appSession.exec("node server.js");

Use separate sandboxes when:

  • You need complete isolation (untrusted code)
  • Different users require fully separated environments
  • Independent resource allocation is needed

Best practices

Clean up temporary sessions:

TypeScript
try {
const session = await sandbox.createSession({ name: 'temp' });
await session.exec('command');
} finally {
await sandbox.deleteSession('temp');
}

Sessions share filesystem:

TypeScript
// Bad - affects all sessions
await session.exec('rm -rf /workspace/*');
// Use separate sandboxes for untrusted isolation
const userSandbox = getSandbox(env.Sandbox, userId);