> ## Documentation Index
> Fetch the complete documentation index at: https://novita.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Auto Pause and Resume

export const SandboxConfigHint = () => {
  if (typeof document === "undefined") {
    return null;
  } else {
    return <Note>Before running the example code in this document, please ensure you have properly configured environment variables. For details, please refer to <a href="/guides/sandbox-your-first-agent-sandbox#configure-environment-variables">Configure Environment Variables</a>.</Note>;
  }
};

These features build on [Sandbox Persistence](/guides/sandbox-persistence). Auto-pause keeps sandbox state when the maximum lifetime expires. Auto-resume wakes a paused sandbox when new activity arrives.

<SandboxConfigHint />

## Configure

When creating a sandbox, pass a `lifecycle` configuration. This controls timeout behavior and whether a paused sandbox can wake automatically.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox'

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

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.core import Sandbox

  sandbox = Sandbox.create(
      timeout=10 * 60,
      lifecycle={
          "on_timeout": "pause",
          "auto_resume": True,  # resume when activity arrives
      },
  )
  ```
</CodeGroup>

### Lifecycle options

The `lifecycle` setting supports these fields:

| Setting                                    | Option    | Meaning                                                                                                   |
| ------------------------------------------ | --------- | --------------------------------------------------------------------------------------------------------- |
| `onTimeout` (JS) / `on_timeout` (Python)   | `"kill"`  | Default behavior. The sandbox is removed after its timeout.                                               |
| `onTimeout` (JS) / `on_timeout` (Python)   | `"pause"` | The sandbox is paused after the timeout instead of being deleted.                                         |
| `autoResume` (JS) / `auto_resume` (Python) | `false`   | Default behavior. Paused sandboxes stay paused until resumed manually.                                    |
| `autoResume` (JS) / `auto_resume` (Python) | `true`    | Paused sandboxes restart when supported activity arrives. This requires timeout behavior to be `"pause"`. |

If auto-resume is disabled or omitted, a paused sandbox can still be resumed manually with `Sandbox.connect()`.

## Auto-pause

By default, a sandbox is killed when its timeout expires. To keep the state instead, set `onTimeout` in JavaScript or `on_timeout` in Python to pause on timeout.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox/code-interpreter'

  const sandbox = await Sandbox.create({
    timeoutMs: 300_000,
    lifecycle: {
      onTimeout: 'pause',
      autoResume: false,
    },
  })

  await sandbox.kill()
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.code_interpreter import Sandbox

  sandbox = Sandbox.create(
      timeout=300,
      lifecycle={
          "on_timeout": "pause",
          "auto_resume": False,
      },
  )

  sandbox.kill()
  ```
</CodeGroup>

## Auto-resume

Auto-resume can wake a paused sandbox when supported activity arrives. This works only when the sandbox is configured to pause on timeout.

### Timeout after auto-resume

After an automatic resume, the sandbox gets a timeout of at least five minutes. If the original timeout was longer than five minutes, the longer original value is reused.

The timeout timer starts when the sandbox resumes, not when it was originally created.

Example with a two-minute timeout:

1. The sandbox runs for two minutes and then pauses.
2. New activity reaches the sandbox, causing it to resume.
3. The resumed sandbox receives a five-minute timeout because that is the minimum.
4. If nothing resets the timer, the sandbox pauses again after five minutes.

Example with a one-hour timeout:

* The sandbox resumes with a one-hour timeout, because the original timeout is longer than the five-minute minimum.

This behavior continues across future pause and resume cycles, because the lifecycle settings remain attached to the sandbox.

<Note>
  You can update the timeout after resuming by using `setTimeout()` in JavaScript or `set_timeout()` in Python.
</Note>

### What counts as activity

Auto-resume can be triggered by SDK actions and HTTP traffic.

Supported examples include:

* `sandbox.commands.run(...)`
* `sandbox.files.read(...)`
* `sandbox.files.write(...)`
* Visiting a tunneled application URL
* Sending requests to a service running inside the sandbox

When a sandbox is paused and auto-resume is enabled, the next supported action resumes it automatically. You do not need to call `Sandbox.connect()` first.

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

This example creates a sandbox, writes a file, pauses the sandbox, and then reads the file. The read operation causes the sandbox to resume.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox'

  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}`)
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.core import Sandbox

  sandbox = Sandbox.create(
      timeout=10 * 60,
      lifecycle={
          "on_timeout": "pause",
          "auto_resume": True,
      },
  )

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

  content = sandbox.files.read("/home/user/hello.txt")
  print(content)
  print(f"State after read: {sandbox.get_info().state}")
  ```
</CodeGroup>

### Example: Web server with auto-resume

Auto-resume works well for preview environments and web servers. After the sandbox pauses, an incoming HTTP request to the exposed service can wake it.

The example below starts a simple Python HTTP server and prints a public preview URL. You can use `getHost()` in JavaScript or `get_host()` in Python to retrieve the public hostname for a port.

<CodeGroup>
  ```js JavaScript & TypeScript icon="js" theme={"system"}
  import { Sandbox } from 'novita-sandbox'

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

  await sandbox.commands.run('python3 -m http.server 3000', { background: true })

  const host = sandbox.getHost(3000)
  // Once the sandbox times out and pauses, any request to the preview URL will automatically resume it.
  console.log(`Preview URL: https://${host}`)
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.core import Sandbox

  sandbox = Sandbox.create(
      timeout=5 * 60,
      lifecycle={
          "on_timeout": "pause",
          "auto_resume": True,
      },
  )

  sandbox.commands.run("python3 -m http.server 3000", background=True)

  host = sandbox.get_host(3000)
  # Once the sandbox times out and pauses, any request to the preview URL will automatically resume it.
  print(f"Preview URL: https://{host}")
  ```
</CodeGroup>

## Cleanup

Auto-resume remains enabled across repeated resume and pause cycles. Every resume starts a new timeout period, using at least five minutes or the longer original timeout.

After the sandbox resumes, clients should reconnect to any services they were using. Existing HTTP, WebSocket, database, and terminal connections do not stay open while the sandbox is paused.

You can call `.kill()` to delete the sandbox permanently. After that, it cannot be resumed.
