Skip to content

Commit 516c346

Browse files
beran-tmishushakov
andauthored
Tighten AutoResume docs and trim use-case examples (#200)
* Tighten AutoResume docs and trim use-case examples Rename title to "Auto resume", add a description, and restructure the page around a single web server example. Removes the agent/tool and per-user sandbox use cases. * Move auto-resume note into code comments * Address review comments on auto-resume docs - Retitle to "Auto-resume on request" - Replace "AutoResume" with "Auto-resume" throughout - Convert lifecycle options list into a table - Reframe option names as "onTimeout (JavaScript) / on_timeout (Python)" - Qualify option references with the `lifecycle.` prefix - Restore the standalone Cleanup section * updated --------- Co-authored-by: Mish Ushakov <10400064+mishushakov@users.noreply.github.com>
1 parent 290b9ef commit 516c346

1 file changed

Lines changed: 39 additions & 191 deletions

File tree

docs/sandbox/auto-resume.mdx

Lines changed: 39 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
---
2-
title: "AutoResume"
3-
sidebarTitle: AutoResume
2+
title: "Auto-resume on request"
3+
sidebarTitle: Auto-resume on request
4+
description: "Manage sandbox lifecycle and auto-resume on activity."
45
---
56

6-
Many workloads don't need a sandbox running all the time, but when they do need it, it should just work, whether it was paused or not.
7+
Many workloads don't need a sandbox running all the time, but when they do, it should just workwhether the sandbox was paused or not.
78

8-
`AutoResume` handles this automatically: a paused sandbox wakes up when activity arrives, so your code does not have to check or manage sandbox state.
9-
Configure it through the `lifecycle` object when creating a sandbox.
9+
Auto-resume handles this automatically: a paused sandbox wakes up when activity arrives, so your code doesn't have to check or manage sandbox state. Auto-resume builds on the sandbox [persistence](/docs/sandbox/persistence) lifecycle.
1010

11-
## Configure lifecycle on create
11+
## Configure
12+
13+
Set the `lifecycle` object when creating a sandbox to control what happens on timeout and whether paused sandboxes should auto-resume.
1214

1315
<CodeGroup>
1416
```js JavaScript & TypeScript
@@ -35,24 +37,18 @@ sandbox = Sandbox.create(
3537
```
3638
</CodeGroup>
3739

38-
## Lifecycle options
39-
40-
- `onTimeout` / `on_timeout`
41-
- `kill` (default): sandbox is terminated when timeout is reached
42-
- `pause`: sandbox is paused when timeout is reached
43-
- `autoResume` / `auto_resume`
44-
- `false` (default): paused sandboxes do not auto-resume
45-
- `true`: paused sandboxes auto-resume on activity
46-
- `true` is valid only when `onTimeout`/`on_timeout` is `pause`
40+
### Lifecycle options
4741

48-
## Behavior summary
42+
The `lifecycle` object accepts the following options:
4943

50-
- Default behavior is equivalent to `onTimeout: "kill"` with `autoResume: false`.
51-
- `onTimeout: "pause"` with `autoResume: false` gives auto-pause without auto-resume.
52-
- `onTimeout: "pause"` with `autoResume: true` gives auto-pause with auto-resume.
53-
- [`Sandbox.connect()`](/docs/sandbox/connect) can still be used to resume a paused sandbox manually.
44+
| Setting | Option | Description |
45+
|---------|--------|-------------|
46+
| `onTimeout` (JavaScript) / `on_timeout` (Python) | `"kill"` | (default) Sandbox is terminated when timeout is reached |
47+
| | `"pause"` | Sandbox is paused when timeout is reached |
48+
| `autoResume` (JavaScript) / `auto_resume` (Python) | `false` | (default) Paused sandboxes do not auto-resume |
49+
| | `true` | Paused sandboxes auto-resume on activity. Valid only when `onTimeout` / `on_timeout` is set to `"pause"` |
5450

55-
If you use `autoResume: false`, resume explicitly with [`Sandbox.connect()`](/docs/sandbox/connect).
51+
If `lifecycle.autoResume` / `lifecycle.auto_resume` is falsy or unset, you can still resume a paused sandbox manually with [`Sandbox.connect()`](/docs/sandbox/connect).
5652

5753
## Timeout after auto-resume
5854

@@ -68,26 +64,28 @@ For example, if you create a sandbox with a 2-minute timeout:
6864

6965
If you create a sandbox with a 1-hour timeout, the auto-resume timeout will also be 1 hour, since it exceeds the 5-minute minimum.
7066

71-
This cycle repeats every time the sandbox auto-resumes — the lifecycle configuration (`onTimeout: "pause"` + `autoResume: true`) is persistent across pause/resume cycles.
67+
This cycle repeats every time the sandbox auto-resumes — the lifecycle configuration is persistent across pause/resume cycles.
7268

7369
<Note>
74-
You can change the timeout after the sandbox resumes by calling `setTimeout`/`set_timeout`. See [Change sandbox timeout during runtime](/docs/sandbox#change-sandbox-timeout-during-runtime).
70+
You can change the timeout after the sandbox resumes by calling `setTimeout()` (JavaScript) / `set_timeout()` (Python). See [Change sandbox timeout during runtime](/docs/sandbox#change-sandbox-timeout-during-runtime).
7571
</Note>
7672

7773
## What counts as activity
7874

79-
Auto-resume is triggered by the sandbox activity - that's both HTTP traffic and controlling the sandbox from the SDK.
75+
Auto-resume is triggered by sandbox activity both HTTP traffic and SDK operations.
8076

81-
That includes SDK operations like:
77+
That includes:
8278
- `sandbox.commands.run(...)`
8379
- `sandbox.files.read(...)`
8480
- `sandbox.files.write(...)`
85-
- opening a tunneled app URL or sending requests to a service running inside the sandbox
81+
- Opening a tunneled app URL or sending requests to a service running inside the sandbox
8682

87-
If a sandbox is paused and `autoResume` is enabled, the next supported operation resumes it automatically. You do not need to call [`Sandbox.connect()`](/docs/sandbox/connect) first.
83+
If a sandbox is paused and `lifecycle.autoResume` (JavaScript) / `lifecycle.auto_resume` (Python) is enabled, the next supported operation resumes it automatically. You do not need to call [`Sandbox.connect()`](/docs/sandbox/connect) first.
8884

8985
### SDK example: pause, then read a file
9086

87+
The following example writes a file, pauses the sandbox, then reads the file back. The read operation triggers an automatic resume.
88+
9189
<CodeGroup>
9290
```js JavaScript & TypeScript
9391
import { Sandbox } from 'e2b'
@@ -127,108 +125,16 @@ print(f"State after read: {sandbox.get_info().state}")
127125
```
128126
</CodeGroup>
129127

130-
## Use cases
131-
132-
### Web and dev/preview servers
133-
134-
Use `onTimeout: "pause"` + `autoResume: true` so inbound traffic can wake a paused sandbox automatically.
135-
This works for both:
136-
- Basic web/API servers
137-
- Dev or preview servers you open occasionally
138-
139-
<CodeGroup>
140-
```js JavaScript & TypeScript
141-
import { Sandbox } from 'e2b'
142-
143-
const sandbox = await Sandbox.create({
144-
timeoutMs: 10 * 60 * 1000,
145-
lifecycle: {
146-
onTimeout: 'pause',
147-
autoResume: true,
148-
},
149-
})
150-
151-
await sandbox.commands.run(
152-
`python3 -m pip -q install 'flask>=2.2'`
153-
)
154-
155-
await sandbox.files.write(
156-
'/home/user/app.py',
157-
[
158-
'from flask import Flask',
159-
'app = Flask(__name__)',
160-
'@app.route("/")',
161-
'def hello():',
162-
' return "Hello, World!"',
163-
'app.run(host="0.0.0.0", port=3000)',
164-
'',
165-
].join('\n')
166-
)
167-
168-
await sandbox.commands.run(
169-
'python3 -u /home/user/app.py > /home/user/flask.log 2>&1',
170-
{ background: true }
171-
)
172-
173-
await new Promise((resolve) => setTimeout(resolve, 1000))
174-
175-
const previewHost = sandbox.getHost(3000)
176-
console.log(`Preview URL: https://${previewHost}`)
177-
178-
console.log(`Status before pause: ${(await sandbox.getInfo()).state}`)
179-
await sandbox.pause()
180-
console.log(`Status after pause: ${(await sandbox.getInfo()).state}`)
181-
```
182-
```python Python
183-
import time
184-
185-
from e2b import Sandbox
186-
187-
sandbox = Sandbox.create(
188-
timeout=10 * 60,
189-
lifecycle={
190-
"on_timeout": "pause",
191-
"auto_resume": True,
192-
},
193-
)
194-
195-
sandbox.commands.run("python3 -m pip -q install 'flask>=2.2'")
196-
197-
sandbox.files.write(
198-
"/home/user/app.py",
199-
'from flask import Flask\n'
200-
'app = Flask(__name__)\n'
201-
'@app.route("/")\n'
202-
'def hello():\n'
203-
' return "Hello, World!"\n'
204-
'app.run(host="0.0.0.0", port=3000)\n'
205-
)
128+
## Example: Web server with auto-resume
206129

207-
sandbox.commands.run(
208-
"python3 -u /home/user/app.py > /home/user/flask.log 2>&1",
209-
background=True,
210-
)
130+
Auto-resume is especially useful for web servers and preview environments. When an HTTP request arrives at a paused sandbox, the sandbox wakes up automatically to handle it.
211131

212-
time.sleep(1)
213-
214-
preview_host = sandbox.get_host(3000)
215-
print(f"Preview URL: https://{preview_host}")
216-
217-
print(f"Status before pause: {sandbox.get_info().state}")
218-
sandbox.pause()
219-
print(f"Status after pause: {sandbox.get_info().state}")
220-
```
221-
</CodeGroup>
222-
223-
### Agent/tool execution
224-
225-
For queued tasks or tool calls, create once and keep using the same sandbox handle. If it is paused, it will auto-resume when you run the next command.
132+
The following example starts a simple HTTP server and retrieves its public URL. Use [`getHost()`](/docs/sandbox/internet-access#sandbox-public-url) (JavaScript) / [`get_host()`](/docs/sandbox/internet-access#sandbox-public-url) (Python) to get the sandbox's publicly accessible hostname for a given port.
226133

227134
<CodeGroup>
228135
```js JavaScript & TypeScript
229136
import { Sandbox } from 'e2b'
230137

231-
// One-time setup
232138
const sandbox = await Sandbox.create({
233139
timeoutMs: 5 * 60 * 1000,
234140
lifecycle: {
@@ -237,18 +143,15 @@ const sandbox = await Sandbox.create({
237143
},
238144
})
239145

240-
// Later: called for each agent/tool task
241-
async function runToolTask(command) {
242-
const result = await sandbox.commands.run(command)
243-
return result.stdout
244-
}
146+
await sandbox.commands.run('python3 -m http.server 3000', { background: true })
245147

246-
console.log(await runToolTask('python -c "print(2 + 2)"'))
148+
const host = sandbox.getHost(3000)
149+
// Once the sandbox times out and pauses, any request to the preview URL will automatically resume it.
150+
console.log(`Preview URL: https://${host}`)
247151
```
248152
```python Python
249153
from e2b import Sandbox
250154

251-
# One-time setup
252155
sandbox = Sandbox.create(
253156
timeout=5 * 60,
254157
lifecycle={
@@ -257,72 +160,17 @@ sandbox = Sandbox.create(
257160
},
258161
)
259162

260-
# Later: called for each agent/tool task
261-
def run_tool_task(command: str) -> str:
262-
result = sandbox.commands.run(command)
263-
return result.stdout
264-
265-
print(run_tool_task('python -c "print(2 + 2)"'))
266-
```
267-
</CodeGroup>
268-
269-
### Per-user sandboxes
163+
sandbox.commands.run("python3 -m http.server 3000", background=True)
270164

271-
For multi-tenant apps, keep a map of sandbox IDs by user. On each request, connect to the user's existing sandbox (which auto-resumes if paused) or create a new one.
272-
273-
<CodeGroup>
274-
```js JavaScript & TypeScript
275-
import { Sandbox } from 'e2b'
276-
277-
const userSandboxes = new Map() // userId → Sandbox
278-
279-
async function getSandbox(userId) {
280-
let sandbox = userSandboxes.get(userId)
281-
282-
if (!sandbox) {
283-
sandbox = await Sandbox.create({
284-
timeoutMs: 5 * 60 * 1000,
285-
lifecycle: {
286-
onTimeout: 'pause',
287-
autoResume: true,
288-
},
289-
})
290-
userSandboxes.set(userId, sandbox)
291-
}
292-
293-
return sandbox
294-
}
295-
296-
// On each user request (auto-resumes if paused)
297-
const sandbox = await getSandbox('user-123')
298-
const result = await sandbox.commands.run('echo "Hello from your sandbox"')
299-
console.log(result.stdout)
300-
```
301-
```python Python
302-
from e2b import Sandbox
303-
304-
user_sandboxes: dict[str, Sandbox] = {} # user_id → Sandbox
305-
306-
def get_sandbox(user_id: str) -> Sandbox:
307-
if user_id not in user_sandboxes:
308-
user_sandboxes[user_id] = Sandbox.create(
309-
timeout=5 * 60,
310-
lifecycle={
311-
"on_timeout": "pause",
312-
"auto_resume": True,
313-
},
314-
)
315-
316-
return user_sandboxes[user_id]
317-
318-
# On each user request (auto-resumes if paused)
319-
sandbox = get_sandbox("user-123")
320-
result = sandbox.commands.run('echo "Hello from your sandbox"')
321-
print(result.stdout)
165+
host = sandbox.get_host(3000)
166+
# Once the sandbox times out and pauses, any request to the preview URL will automatically resume it.
167+
print(f"Preview URL: https://{host}")
322168
```
323169
</CodeGroup>
324170

325171
## Cleanup
326-
Auto-resume is persistent, meaning if your sandbox resumes and later times out again, it will pause again.
172+
173+
Auto-resume is persistent — if your sandbox resumes and later times out again, it will pause again.
327174
Each time the sandbox resumes, it gets a fresh timeout (at least 5 minutes, or longer if the original creation timeout exceeds that) — so the sandbox keeps cycling between running and paused as long as activity arrives.
175+
328176
If you call `.kill()`, the sandbox is permanently deleted and cannot be resumed.

0 commit comments

Comments
 (0)