Skip to content

Commit 060be1a

Browse files
whoiskatrinOxyjun
andauthored
add docs for keepAlive flag (#26121)
* add docs for keepAlive flag * fix timeout value * update docs * PCX review --------- Co-authored-by: Jun Lee <junlee@cloudflare.com>
1 parent 930bc3a commit 060be1a

File tree

5 files changed

+144
-17
lines changed

5 files changed

+144
-17
lines changed

src/content/docs/sandbox/api/sessions.mdx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Create isolated execution contexts within a sandbox. Each session maintains its
1313
Every sandbox has a default session that automatically maintains shell state. Create additional sessions when you need isolated shell contexts for different environments or parallel workflows.
1414
:::
1515

16+
:::note
17+
For sandbox-level configuration options like `keepAlive`, refer to the [Sandbox options configuration](/sandbox/configuration/sandbox-options/).
18+
:::
19+
1620
## Methods
1721

1822
### `createSession()`
@@ -120,7 +124,9 @@ await sandbox.destroy(): Promise<void>
120124
```
121125

122126
:::note
123-
Containers automatically sleep after 3 minutes of inactivity, but still count toward account limits. Use `destroy()` to immediately free up resources.
127+
Containers automatically sleep after 10 minutes of inactivity, but still count toward account limits. Use `destroy()` to immediately free up resources.
128+
129+
**Important**: When using [`keepAlive: true`](/sandbox/configuration/sandbox-options/#keepalive), containers will not automatically timeout, so calling `destroy()` is **required** to prevent containers running indefinitely.
124130
:::
125131

126132
<TypeScriptExample>
@@ -143,10 +149,10 @@ async function executeCode(code: string): Promise<string> {
143149

144150
The `ExecutionSession` object has all sandbox methods bound to the specific session:
145151

146-
**Commands**: [`exec()`](/sandbox/api/commands/#exec), [`execStream()`](/sandbox/api/commands/#execstream)
147-
**Processes**: [`startProcess()`](/sandbox/api/commands/#startprocess), [`listProcesses()`](/sandbox/api/commands/#listprocesses), [`killProcess()`](/sandbox/api/commands/#killprocess), [`killAllProcesses()`](/sandbox/api/commands/#killallprocesses), [`getProcessLogs()`](/sandbox/api/commands/#getprocesslogs), [`streamProcessLogs()`](/sandbox/api/commands/#streamprocesslogs)
148-
**Files**: [`writeFile()`](/sandbox/api/files/#writefile), [`readFile()`](/sandbox/api/files/#readfile), [`mkdir()`](/sandbox/api/files/#mkdir), [`deleteFile()`](/sandbox/api/files/#deletefile), [`renameFile()`](/sandbox/api/files/#renamefile), [`moveFile()`](/sandbox/api/files/#movefile), [`gitCheckout()`](/sandbox/api/files/#gitcheckout)
149-
**Environment**: [`setEnvVars()`](/sandbox/api/sessions/#setenvvars)
152+
**Commands**: [`exec()`](/sandbox/api/commands/#exec), [`execStream()`](/sandbox/api/commands/#execstream)
153+
**Processes**: [`startProcess()`](/sandbox/api/commands/#startprocess), [`listProcesses()`](/sandbox/api/commands/#listprocesses), [`killProcess()`](/sandbox/api/commands/#killprocess), [`killAllProcesses()`](/sandbox/api/commands/#killallprocesses), [`getProcessLogs()`](/sandbox/api/commands/#getprocesslogs), [`streamProcessLogs()`](/sandbox/api/commands/#streamprocesslogs)
154+
**Files**: [`writeFile()`](/sandbox/api/files/#writefile), [`readFile()`](/sandbox/api/files/#readfile), [`mkdir()`](/sandbox/api/files/#mkdir), [`deleteFile()`](/sandbox/api/files/#deletefile), [`renameFile()`](/sandbox/api/files/#renamefile), [`moveFile()`](/sandbox/api/files/#movefile), [`gitCheckout()`](/sandbox/api/files/#gitcheckout)
155+
**Environment**: [`setEnvVars()`](/sandbox/api/sessions/#setenvvars)
150156
**Code Interpreter**: [`createCodeContext()`](/sandbox/api/interpreter/#createcodecontext), [`runCode()`](/sandbox/api/interpreter/#runcode), [`listCodeContexts()`](/sandbox/api/interpreter/#listcodecontexts), [`deleteCodeContext()`](/sandbox/api/interpreter/#deletecodecontext)
151157

152158
## Related resources

src/content/docs/sandbox/concepts/sandboxes.mdx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,17 @@ A sandbox is an isolated execution environment where your code runs. Each sandbo
2020
A sandbox is created the first time you reference its ID:
2121

2222
```typescript
23-
const sandbox = getSandbox(env.Sandbox, 'user-123');
23+
const sandbox = getSandbox(env.Sandbox, "user-123");
2424
await sandbox.exec('echo "Hello"'); // First request creates sandbox
2525
```
2626

27-
**Duration**: 100-300ms (cold start) or \<10ms (if warm)
28-
2927
### Active
3028

3129
The sandbox container is running and processing requests. All state remains available: files, running processes, shell sessions, and environment variables.
3230

3331
### Idle
3432

35-
After a period of inactivity, the container stops to free resources. When the next request arrives, a fresh container starts. All previous state is lost and the environment resets to its initial state.
33+
After a period of inactivity (10 minutes by default), the container stops to free resources. When the next request arrives, a fresh container starts. All previous state is lost and the environment resets to its initial state.
3634

3735
### Destruction
3836

@@ -48,12 +46,14 @@ await sandbox.destroy();
4846
Sandbox state exists only while the container is active. Understanding this is critical for building reliable applications.
4947

5048
**While the container is active** (typically minutes to hours of activity):
49+
5150
- Files written to `/workspace`, `/tmp`, `/home` remain available
5251
- Background processes continue running
5352
- Shell sessions maintain their working directory and environment
5453
- Code interpreter contexts retain variables and imports
5554

5655
**When the container stops** (due to inactivity or explicit destruction):
56+
5757
- All files are deleted
5858
- All processes terminate
5959
- All shell state resets
@@ -95,6 +95,7 @@ Idempotent operations with clear task-to-sandbox mapping. Good for builds, pipel
9595
The first request to a sandbox determines its geographic location. Subsequent requests route to the same location.
9696

9797
**For global apps**:
98+
9899
- Option 1: Multiple sandboxes per user with region suffix (`user-123-us`, `user-123-eu`)
99100
- Option 2: Single sandbox per user (simpler, but some users see higher latency)
100101

@@ -104,10 +105,10 @@ The first request to a sandbox determines its geographic location. Subsequent re
104105

105106
```typescript
106107
try {
107-
const sandbox = getSandbox(env.Sandbox, sessionId);
108-
await sandbox.exec('npm run build');
108+
const sandbox = getSandbox(env.Sandbox, sessionId);
109+
await sandbox.exec("npm run build");
109110
} finally {
110-
await sandbox.destroy(); // Clean up temporary sandboxes
111+
await sandbox.destroy(); // Clean up temporary sandboxes
111112
}
112113
```
113114

@@ -121,13 +122,13 @@ Containers restart after inactivity or failures. Design your application to hand
121122

122123
```typescript
123124
// Check if required files exist before using them
124-
const files = await sandbox.listFiles('/workspace');
125-
if (!files.includes('data.json')) {
126-
// Reinitialize: container restarted and lost previous state
127-
await sandbox.writeFile('/workspace/data.json', initialData);
125+
const files = await sandbox.listFiles("/workspace");
126+
if (!files.includes("data.json")) {
127+
// Reinitialize: container restarted and lost previous state
128+
await sandbox.writeFile("/workspace/data.json", initialData);
128129
}
129130

130-
await sandbox.exec('python process.py');
131+
await sandbox.exec("python process.py");
131132
```
132133

133134
## Best practices

src/content/docs/sandbox/configuration/index.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ Configure your Sandbox SDK deployment with Wrangler, customize container images,
3737
Pass configuration and secrets to your sandboxes using environment variables.
3838
</LinkTitleCard>
3939

40+
<LinkTitleCard
41+
title="Sandbox options"
42+
href="/sandbox/configuration/sandbox-options/"
43+
icon="setting"
44+
>
45+
Configure sandbox behavior with options like `keepAlive` for long-running processes.
46+
</LinkTitleCard>
47+
4048
</CardGrid>
4149

4250
## Related resources
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
title: Sandbox options
3+
pcx_content_type: configuration
4+
sidebar:
5+
order: 4
6+
---
7+
8+
import { TypeScriptExample } from "~/components";
9+
10+
Configure sandbox behavior by passing options when creating a sandbox instance with `getSandbox()`.
11+
12+
## Available options
13+
14+
```ts
15+
import { getSandbox } from '@cloudflare/sandbox';
16+
17+
const sandbox = getSandbox(binding, sandboxId, options?: SandboxOptions);
18+
```
19+
20+
### keepAlive
21+
22+
**Type**: `boolean`
23+
**Default**: `false`
24+
25+
Keep the container alive indefinitely by preventing automatic shutdown. When `true`, the container will never auto-timeout and must be explicitly destroyed using `destroy()`.
26+
27+
<TypeScriptExample>
28+
```ts
29+
// For long-running processes that need the container to stay alive
30+
const sandbox = getSandbox(env.Sandbox, 'user-123', {
31+
keepAlive: true
32+
});
33+
34+
// Run your long-running process
35+
await sandbox.startProcess('python long_running_script.py');
36+
37+
// Important: Must explicitly destroy when done
38+
try {
39+
// Your work here
40+
} finally {
41+
await sandbox.destroy(); // Required to prevent containers running indefinitely
42+
}
43+
```
44+
</TypeScriptExample>
45+
46+
:::caution[Resource management with keepAlive]
47+
When `keepAlive: true` is set, containers will not automatically timeout. They must be explicitly destroyed using `destroy()` to prevent containers running indefinitely and counting toward your account limits.
48+
:::
49+
50+
## When to use keepAlive
51+
52+
Use `keepAlive: true` for:
53+
54+
- **Long-running builds** - CI/CD pipelines that may have idle periods between steps
55+
- **Batch processing** - Jobs that process data in waves with gaps between batches
56+
- **Monitoring tasks** - Processes that periodically check external services
57+
- **Interactive sessions** - User-driven workflows where the container should remain available
58+
59+
By default, containers automatically shut down after 10 minutes of inactivity. The `keepAlive` option prevents this automatic shutdown.
60+
61+
## Related resources
62+
63+
- [Background processes guide](/sandbox/guides/background-processes/) - Using `keepAlive` with long-running processes
64+
- [Sessions API reference](/sandbox/api/sessions/) - Container lifecycle management
65+
- [Sandboxes concept](/sandbox/concepts/sandboxes/) - Understanding sandbox lifecycle

src/content/docs/sandbox/guides/background-processes.mdx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,57 @@ console.log('All services running');
159159
```
160160
</TypeScriptExample>
161161

162+
## Keep containers alive for long-running processes
163+
164+
By default, containers automatically shut down after 10 minutes of inactivity. For long-running processes that may have idle periods (like CI/CD pipelines, batch jobs, or monitoring tasks), use the [`keepAlive` option](/sandbox/configuration/sandbox-options/#keepalive):
165+
166+
<TypeScriptExample>
167+
```ts
168+
import { getSandbox, parseSSEStream, type LogEvent } from '@cloudflare/sandbox';
169+
170+
export default {
171+
async fetch(request: Request, env: Env): Promise<Response> {
172+
// Enable keepAlive for long-running processes
173+
const sandbox = getSandbox(env.Sandbox, 'build-job-123', {
174+
keepAlive: true
175+
});
176+
177+
try {
178+
// Start a long-running build process
179+
const build = await sandbox.startProcess('npm run build:production');
180+
181+
// Monitor progress
182+
const logs = await sandbox.streamProcessLogs(build.id);
183+
184+
// Process can run indefinitely without container shutdown
185+
for await (const log of parseSSEStream<LogEvent>(logs)) {
186+
console.log(log.data);
187+
if (log.data.includes('Build complete')) {
188+
break;
189+
}
190+
}
191+
192+
return new Response('Build completed');
193+
} finally {
194+
// Important: Must explicitly destroy when done
195+
await sandbox.destroy();
196+
}
197+
}
198+
};
199+
```
200+
</TypeScriptExample>
201+
202+
:::caution[Always destroy with keepAlive]
203+
When using `keepAlive: true`, containers will not automatically timeout. You **must** call `sandbox.destroy()` when finished to prevent containers running indefinitely and counting toward your account limits.
204+
:::
205+
162206
## Best practices
163207

164208
- **Wait for readiness** - Stream logs to detect when services are ready
165209
- **Clean up** - Always stop processes when done
166210
- **Handle failures** - Monitor logs for errors and restart if needed
167211
- **Use try/finally** - Ensure cleanup happens even on errors
212+
- **Use `keepAlive` for long-running tasks** - Prevent container shutdown during processes with idle periods
168213

169214
## Troubleshooting
170215

@@ -199,6 +244,8 @@ const server = await sandbox.startProcess('node server.js');
199244
## Related resources
200245

201246
- [Commands API reference](/sandbox/api/commands/) - Complete process management API
247+
- [Sandbox options configuration](/sandbox/configuration/sandbox-options/) - Configure `keepAlive` and other options
248+
- [Sessions API reference](/sandbox/api/sessions/) - Container lifecycle management
202249
- [Execute commands guide](/sandbox/guides/execute-commands/) - One-time command execution
203250
- [Expose services guide](/sandbox/guides/expose-services/) - Make processes accessible
204251
- [Streaming output guide](/sandbox/guides/streaming-output/) - Monitor process output

0 commit comments

Comments
 (0)