diff --git a/src/content/docs/sandbox/concepts/architecture.mdx b/src/content/docs/sandbox/concepts/architecture.mdx index 08d17f29873616..b414f78fb62f75 100644 --- a/src/content/docs/sandbox/concepts/architecture.mdx +++ b/src/content/docs/sandbox/concepts/architecture.mdx @@ -26,7 +26,7 @@ flowchart TB DO["Sandbox Durable Object routes requests & maintains state"] Container["Isolated Ubuntu container executes untrusted code safely"] - DO -->|HTTP API| Container + DO -->|HTTP or WebSocket| Container end Worker -->|RPC call via the Durable Object stub returned by `getSandbox`| DO @@ -91,13 +91,32 @@ When you execute a command: await sandbox.exec("python script.py"); ``` -1. **Client SDK** validates parameters and sends HTTP request to Durable Object +1. **Client SDK** validates parameters and sends request to Durable Object 2. **Durable Object** authenticates and routes to container runtime 3. **Container Runtime** validates inputs, executes command, captures output 4. **Response flows back** through all layers with proper error transformation +## Transport layer + +The SDK supports two communication modes between the Durable Object and container: + +**HTTP transport (default)** - Each SDK operation creates a separate HTTP request to the container API. Simple and reliable for typical workloads. + +**WebSocket transport** - All SDK operations multiplex over a single persistent WebSocket connection. Reduces sub-request count for high-frequency operations. + +Configure via the `transportMode` option: + +```typescript +const sandbox = getSandbox(env.Sandbox, 'my-sandbox', { + transportMode: 'websocket' // or 'http' (default) +}); +``` + +Both modes provide identical functionality. WebSocket mode is beneficial when approaching [sub-request limits](/workers/platform/limits/#subrequests) in Workers or Durable Objects. + ## Related resources +- [Sandbox options](/sandbox/configuration/sandbox-options/) - Configure transport mode and other options - [Sandbox lifecycle](/sandbox/concepts/sandboxes/) - How sandboxes are created and managed - [Container runtime](/sandbox/concepts/containers/) - Inside the execution environment - [Security model](/sandbox/concepts/security/) - How isolation and validation work diff --git a/src/content/docs/sandbox/configuration/sandbox-options.mdx b/src/content/docs/sandbox/configuration/sandbox-options.mdx index 2b9db51b990ee0..e73fb7685cb5aa 100644 --- a/src/content/docs/sandbox/configuration/sandbox-options.mdx +++ b/src/content/docs/sandbox/configuration/sandbox-options.mdx @@ -108,6 +108,68 @@ const sandbox2 = getSandbox(env.Sandbox, 'user-env', { Precedence: `options` > `env vars` > SDK defaults +### transportMode + +**Type**: `'http' | 'websocket'` +**Default**: `'http'` + +Communication protocol between the SDK and container runtime. WebSocket mode multiplexes all operations over a single persistent connection, reducing sub-request count. + + +```ts +// HTTP mode (default) - Each operation is a separate HTTP request +const sandbox = getSandbox(env.Sandbox, 'user-123'); + +// WebSocket mode - All operations multiplex over one connection +const sandbox = getSandbox(env.Sandbox, 'user-456', { + transportMode: 'websocket' +}); +``` + + +**When to use WebSocket mode**: + +WebSocket transport is beneficial when running inside Workers or Durable Objects where [sub-request limits](/workers/platform/limits/#subrequests) apply: + +- **Many file operations** - Reading or writing multiple files in sequence +- **Streaming workloads** - Long-running command execution with streaming output +- **Interactive workflows** - Frequent back-and-forth operations (edit, test, debug cycles) +- **Process monitoring** - Polling process status or reading logs repeatedly + + +```ts +// Example: Bulk file operations benefit from WebSocket mode +const sandbox = getSandbox(env.Sandbox, 'build-env', { + transportMode: 'websocket' +}); + +// These operations share a single WebSocket connection +await sandbox.writeFile('/workspace/src/index.ts', sourceCode); +await sandbox.writeFile('/workspace/package.json', packageJson); +await sandbox.writeFile('/workspace/tsconfig.json', tsConfig); + +// Run build and stream output +for await (const event of sandbox.execStream('npm run build')) { + console.log(event); +} + +// Check results +const output = await sandbox.readFile('/workspace/dist/index.js'); +``` + + +:::note[HTTP mode is sufficient for most use cases] +The default HTTP mode works well for typical sandbox operations. Only switch to WebSocket mode if you're approaching sub-request limits or need to optimize for high-frequency operations. +::: + +**Technical details**: + +- WebSocket connection established on first SDK operation +- Automatic reconnection if connection drops +- Request/response matching via unique IDs +- Streaming support via Server-Sent Events over WebSocket +- Transparent to application code (same API regardless of transport mode) + ### Logging **Type**: Environment variables