Skip to main content
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. AutoResume handles this automatically: a paused sandbox wakes up when activity arrives, so your code does not have to check or manage sandbox state. Configure it through the lifecycle object when creating a sandbox.

Configure lifecycle on create

import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create({
  timeoutMs: 10 * 60 * 1000,
  lifecycle: {
    onTimeout: 'pause',
    autoResume: true, // resume when activity arrives
  },
})

Lifecycle options

  • onTimeout / on_timeout
    • kill (default): sandbox is terminated when timeout is reached
    • pause: sandbox is paused when timeout is reached
  • autoResume / auto_resume
    • false (default): paused sandboxes do not auto-resume
    • true: paused sandboxes auto-resume on activity
    • true is valid only when onTimeout/on_timeout is pause

Behavior summary

  • Default behavior is equivalent to onTimeout: "kill" with autoResume: false.
  • onTimeout: "pause" with autoResume: false gives auto-pause without auto-resume.
  • onTimeout: "pause" with autoResume: true gives auto-pause with auto-resume.
  • Sandbox.connect() can still be used to resume a paused sandbox manually.
If you use autoResume: false, resume explicitly with Sandbox.connect().

What counts as activity

Auto-resume is triggered by the sandbox activity - that’s both HTTP traffic and controlling the sandbox from the SDK. That includes SDK operations like:
  • sandbox.commands.run(...)
  • sandbox.files.read(...)
  • sandbox.files.write(...)
  • opening a tunneled app URL or sending requests to a service running inside the sandbox
If a sandbox is paused and autoResume is enabled, the next supported operation resumes it automatically. You do not need to call Sandbox.connect() first.

SDK example: pause, then read a file

import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create({
  timeoutMs: 10 * 60 * 1000,
  lifecycle: {
    onTimeout: 'pause',
    autoResume: true,
  },
})

await sandbox.files.write('/home/user/hello.txt', 'hello from a paused sandbox')
await sandbox.pause()

const content = await sandbox.files.read('/home/user/hello.txt')
console.log(content)
console.log(`State after read: ${(await sandbox.getInfo()).state}`)

Use cases

Web and dev/preview servers

Use onTimeout: "pause" + autoResume: true so inbound traffic can wake a paused sandbox automatically. This works for both:
  • Basic web/API servers
  • Dev or preview servers you open occasionally
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create({
  timeoutMs: 10 * 60 * 1000,
  lifecycle: {
    onTimeout: 'pause',
    autoResume: true,
  },
})

await sandbox.commands.run(
  `python3 -m pip -q install 'flask>=2.2'`
)

await sandbox.files.write(
  '/home/user/app.py',
  [
    'from flask import Flask',
    'app = Flask(__name__)',
    '@app.route("/")',
    'def hello():',
    '    return "Hello, World!"',
    'app.run(host="0.0.0.0", port=3000)',
    '',
  ].join('\n')
)

await sandbox.commands.run(
  'python3 -u /home/user/app.py > /home/user/flask.log 2>&1',
  { background: true }
)

await new Promise((resolve) => setTimeout(resolve, 1000))

const previewHost = sandbox.getHost(3000)
console.log(`Preview URL: https://${previewHost}`)

console.log(`Status before pause: ${(await sandbox.getInfo()).state}`)
await sandbox.pause()
console.log(`Status after pause: ${(await sandbox.getInfo()).state}`)

Agent/tool execution

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.
import { Sandbox } from 'e2b'

// One-time setup
const sandbox = await Sandbox.create({
  timeoutMs: 5 * 60 * 1000,
  lifecycle: {
    onTimeout: 'pause',
    autoResume: true,
  },
})

// Later: called for each agent/tool task
async function runToolTask(command) {
  const result = await sandbox.commands.run(command)
  return result.stdout
}

console.log(await runToolTask('python -c "print(2 + 2)"'))

Per-user sandboxes

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.
import { Sandbox } from 'e2b'

const userSandboxes = new Map() // userId → Sandbox

async function getSandbox(userId) {
  let sandbox = userSandboxes.get(userId)

  if (!sandbox) {
    sandbox = await Sandbox.create({
      timeoutMs: 5 * 60 * 1000,
      lifecycle: {
        onTimeout: 'pause',
        autoResume: true,
      },
    })
    userSandboxes.set(userId, sandbox)
  }

  return sandbox
}

// On each user request (auto-resumes if paused)
const sandbox = await getSandbox('user-123')
const result = await sandbox.commands.run('echo "Hello from your sandbox"')
console.log(result.stdout)

Cleanup

Auto-resume is persistent, meaning if your sandbox resumes and later times out again, it will pause again. If you call .kill(), the sandbox is permanently deleted and cannot be resumed.