|
| 1 | +--- |
| 2 | +title: "AutoResume" |
| 3 | +sidebarTitle: AutoResume |
| 4 | +--- |
| 5 | + |
| 6 | +<Note> |
| 7 | +`AutoResume` and `pause/resume` persistence are available as **Developer Preview**. |
| 8 | + |
| 9 | +Behavior and limits may change as we iterate. Review [Sandbox persistence limitations](/docs/sandbox/persistence#current-limitations-subject-to-change). |
| 10 | +</Note> |
| 11 | + |
| 12 | +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. |
| 13 | + |
| 14 | +`AutoResume` handles this automatically: a paused sandbox wakes up when activity arrives, so your code does not have to check or manage sandbox state. |
| 15 | +Configure it through the `lifecycle` object when creating a sandbox. |
| 16 | + |
| 17 | +## Configure lifecycle on create |
| 18 | + |
| 19 | +<CodeGroup> |
| 20 | +```js JavaScript & TypeScript |
| 21 | +import { Sandbox } from 'e2b' |
| 22 | + |
| 23 | +const sandbox = await Sandbox.create({ |
| 24 | + timeoutMs: 10 * 60 * 1000, |
| 25 | + lifecycle: { |
| 26 | + onTimeout: 'pause', |
| 27 | + autoResume: true, // resume when traffic arrives |
| 28 | + }, |
| 29 | +}) |
| 30 | +``` |
| 31 | +```python Python |
| 32 | +from e2b import Sandbox |
| 33 | + |
| 34 | +sandbox = Sandbox.create( |
| 35 | + timeout=10 * 60, |
| 36 | + lifecycle={ |
| 37 | + "on_timeout": "pause", |
| 38 | + "auto_resume": True, # resume when traffic arrives |
| 39 | + }, |
| 40 | +) |
| 41 | +``` |
| 42 | +</CodeGroup> |
| 43 | + |
| 44 | +## Lifecycle options |
| 45 | + |
| 46 | +- `onTimeout` / `on_timeout` |
| 47 | + - `kill` (default): sandbox is terminated when timeout is reached |
| 48 | + - `pause`: sandbox is paused when timeout is reached |
| 49 | +- `autoResume` / `auto_resume` |
| 50 | + - `false` (default): paused sandboxes do not auto-resume |
| 51 | + - `true`: paused sandboxes auto-resume on activity |
| 52 | + - `true` is valid only when `onTimeout`/`on_timeout` is `pause` |
| 53 | + |
| 54 | +## Behavior summary |
| 55 | + |
| 56 | +- Default behavior is equivalent to `onTimeout: "kill"` with `autoResume: false`. |
| 57 | +- `onTimeout: "pause"` with `autoResume: false` gives auto-pause without auto-resume. |
| 58 | +- `onTimeout: "pause"` with `autoResume: true` gives auto-pause with auto-resume. |
| 59 | +- [`Sandbox.connect()`](/docs/sandbox/connect) can still be used to resume a paused sandbox manually. |
| 60 | + |
| 61 | +If you use `autoResume: false`, resume explicitly with [`Sandbox.connect()`](/docs/sandbox/connect). |
| 62 | + |
| 63 | +## Use cases |
| 64 | + |
| 65 | +### Web and dev/preview servers |
| 66 | + |
| 67 | +Use `onTimeout: "pause"` + `autoResume: true` so inbound traffic can wake a paused sandbox automatically. |
| 68 | +This works for both: |
| 69 | +- Basic web/API servers |
| 70 | +- Dev or preview servers you open occasionally |
| 71 | + |
| 72 | +<CodeGroup> |
| 73 | +```js JavaScript & TypeScript |
| 74 | +import { Sandbox } from 'e2b' |
| 75 | + |
| 76 | +const sandbox = await Sandbox.create({ |
| 77 | + timeoutMs: 10 * 60 * 1000, |
| 78 | + lifecycle: { |
| 79 | + onTimeout: 'pause', |
| 80 | + autoResume: true, |
| 81 | + }, |
| 82 | +}) |
| 83 | + |
| 84 | +// Example: app source already exists in /home/user/app. |
| 85 | +// Replace this command with your API server, Next.js, Vite, etc. |
| 86 | +await sandbox.commands.run( |
| 87 | + 'cd /home/user/app && npm install && npm run dev -- --host 0.0.0.0 --port 3000', |
| 88 | + { background: true } |
| 89 | +) |
| 90 | + |
| 91 | +const previewHost = sandbox.getHost(3000) |
| 92 | +console.log(`Preview URL: https://${previewHost}`) |
| 93 | +``` |
| 94 | +```python Python |
| 95 | +from e2b import Sandbox |
| 96 | + |
| 97 | +sandbox = Sandbox.create( |
| 98 | + timeout=10 * 60, |
| 99 | + lifecycle={ |
| 100 | + "on_timeout": "pause", |
| 101 | + "auto_resume": True, |
| 102 | + }, |
| 103 | +) |
| 104 | + |
| 105 | +# Example: app source already exists in /home/user/app. |
| 106 | +# Replace this command with your API server, Next.js, Vite, etc. |
| 107 | +sandbox.commands.run( |
| 108 | + "cd /home/user/app && npm install && npm run dev -- --host 0.0.0.0 --port 3000", |
| 109 | + background=True, |
| 110 | +) |
| 111 | + |
| 112 | +preview_host = sandbox.get_host(3000) |
| 113 | +print(f"Preview URL: https://{preview_host}") |
| 114 | +``` |
| 115 | +</CodeGroup> |
| 116 | + |
| 117 | +### Agent/tool execution |
| 118 | + |
| 119 | +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. |
| 120 | + |
| 121 | +<CodeGroup> |
| 122 | +```js JavaScript & TypeScript |
| 123 | +import { Sandbox } from 'e2b' |
| 124 | + |
| 125 | +// One-time setup |
| 126 | +const sandbox = await Sandbox.create({ |
| 127 | + timeoutMs: 5 * 60 * 1000, |
| 128 | + lifecycle: { |
| 129 | + onTimeout: 'pause', |
| 130 | + autoResume: true, |
| 131 | + }, |
| 132 | +}) |
| 133 | + |
| 134 | +// Later: called for each agent/tool task |
| 135 | +async function runToolTask(command) { |
| 136 | + const result = await sandbox.commands.run(command) |
| 137 | + return result.stdout |
| 138 | +} |
| 139 | + |
| 140 | +console.log(await runToolTask('python -c "print(2 + 2)"')) |
| 141 | +``` |
| 142 | +```python Python |
| 143 | +from e2b import Sandbox |
| 144 | + |
| 145 | +# One-time setup |
| 146 | +sandbox = Sandbox.create( |
| 147 | + timeout=5 * 60, |
| 148 | + lifecycle={ |
| 149 | + "on_timeout": "pause", |
| 150 | + "auto_resume": True, |
| 151 | + }, |
| 152 | +) |
| 153 | + |
| 154 | +# Later: called for each agent/tool task |
| 155 | +def run_tool_task(command: str) -> str: |
| 156 | + result = sandbox.commands.run(command) |
| 157 | + return result.stdout |
| 158 | + |
| 159 | +print(run_tool_task('python -c "print(2 + 2)"')) |
| 160 | +``` |
| 161 | +</CodeGroup> |
| 162 | + |
| 163 | +### Per-user sandboxes |
| 164 | + |
| 165 | +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. |
| 166 | + |
| 167 | +<CodeGroup> |
| 168 | +```js JavaScript & TypeScript |
| 169 | +import { Sandbox } from 'e2b' |
| 170 | + |
| 171 | +const userSandboxes = new Map() // userId → Sandbox |
| 172 | + |
| 173 | +async function getSandbox(userId) { |
| 174 | + let sandbox = userSandboxes.get(userId) |
| 175 | + |
| 176 | + if (!sandbox) { |
| 177 | + sandbox = await Sandbox.create({ |
| 178 | + timeoutMs: 5 * 60 * 1000, |
| 179 | + lifecycle: { |
| 180 | + onTimeout: 'pause', |
| 181 | + autoResume: true, |
| 182 | + }, |
| 183 | + }) |
| 184 | + userSandboxes.set(userId, sandbox) |
| 185 | + } |
| 186 | + |
| 187 | + return sandbox |
| 188 | +} |
| 189 | + |
| 190 | +// On each user request (auto-resumes if paused) |
| 191 | +const sandbox = await getSandbox('user-123') |
| 192 | +const result = await sandbox.commands.run('echo "Hello from your sandbox"') |
| 193 | +console.log(result.stdout) |
| 194 | +``` |
| 195 | +```python Python |
| 196 | +from e2b import Sandbox |
| 197 | + |
| 198 | +user_sandboxes: dict[str, Sandbox] = {} # user_id → Sandbox |
| 199 | + |
| 200 | +def get_sandbox(user_id: str) -> Sandbox: |
| 201 | + if user_id not in user_sandboxes: |
| 202 | + user_sandboxes[user_id] = Sandbox.create( |
| 203 | + timeout=5 * 60, |
| 204 | + lifecycle={ |
| 205 | + "on_timeout": "pause", |
| 206 | + "auto_resume": True, |
| 207 | + }, |
| 208 | + ) |
| 209 | + |
| 210 | + return user_sandboxes[user_id] |
| 211 | + |
| 212 | +# On each user request (auto-resumes if paused) |
| 213 | +sandbox = get_sandbox("user-123") |
| 214 | +result = sandbox.commands.run('echo "Hello from your sandbox"') |
| 215 | +print(result.stdout) |
| 216 | +``` |
| 217 | +</CodeGroup> |
| 218 | + |
| 219 | +## Cleanup |
| 220 | +Auto-resume is persistent, meaning if your sandbox resumes and later times out again, it will pause again. |
| 221 | + |
| 222 | +If you call `.kill()`, the sandbox is permanently deleted and cannot be resumed. |
0 commit comments