> ## 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.

# Sandbox Persistence

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>;
  }
};

Sandbox persistence lets you pause a sandbox and resume it later with the same filesystem and memory state. This is useful for long-running agent tasks, interactive apps, and workflows that need to survive idle periods without keeping compute resources active.

When a sandbox is paused:

* Files created in the sandbox are preserved.
* In-memory state is preserved, including running processes and variables.
* Network connections are interrupted until the sandbox resumes.
* The sandbox remains stored until you resume and kill it, or kill it while it is paused.

For automatic pause on timeout and auto-resume on activity, see [Auto Pause and Resume](/guides/sandbox-auto-resume). For idle timeout, see [Idle timeout](/guides/sandbox-idle-timeout).

<SandboxConfigHint />

<Warning>
  Please note:

  * It takes about 4 seconds per 1 GB RAM to pause the sandbox.
  * It takes about 1 second to resume the sandbox.
  * The data of a paused sandbox is retained until you explicitly call the `kill` method.
</Warning>

## Pause a sandbox

You can call `pause` method when you want to save the current state.

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

  const sandbox = await Sandbox.create()
  await sandbox.commands.run('echo hello > /tmp/message.txt')

  const sandboxId = sandbox.sandboxId
  await sandbox.pause()

  console.log('Sandbox paused', sandboxId)
  ```

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

  sandbox = Sandbox.create()
  sandbox.commands.run("echo hello > /tmp/message.txt")

  sandbox_id = sandbox.sandbox_id
  sandbox.pause()

  print('Sandbox paused', sandbox_id)
  ```
</CodeGroup>

## Resume a sandbox

Use the saved sandbox ID to connect again. If the sandbox is paused, you can use `connect` method to resumes it before returning.

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

  const sandbox = await Sandbox.connect(sandboxId)
  const result = await sandbox.commands.run('cat /tmp/message.txt')
  console.log(result.stdout)

  await sandbox.kill()
  ```

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

  sandbox = Sandbox.connect(sandbox_id)
  result = sandbox.commands.run("cat /tmp/message.txt")
  print(result.stdout)

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

You can pass a new `timeout` when reconnecting.

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

  const sandbox = await Sandbox.connect(sandboxId, { timeoutMs: 600_000 })

  await sandbox.kill()
  ```

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

  sandbox = Sandbox.connect(sandbox_id, timeout=600)

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

For a running sandbox, the timeout is updated only when the new timeout is longer than the existing one. For a paused sandbox, the timeout applies after it resumes.

## List paused sandboxes

You can use the `list` method with a state filter to find paused sandboxes. More information about using the method can be found in [List Sandboxes](/guides/sandbox-list).

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

  const paginator = Sandbox.list({
    query: {
      state: ['paused'],
    },
  })

  while (paginator.hasNext) {
    const items = await paginator.nextItems()
    for (const info of items) {
      console.log(info.sandboxId, info.state, info.metadata)
    }
  }
  ```

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

  paginator = Sandbox.list(
      query=SandboxQuery(state=[SandboxState.PAUSED])
  )

  while paginator.has_next:
      for info in paginator.next_items():
          print(info.sandbox_id, info.state, info.metadata)
  ```
</CodeGroup>

Metadata filters are useful when you need to find sandboxes created by a specific user, session, or job.

## Delete a paused sandbox

Paused sandboxes remain stored until you remove them. You can use the `kill` method to remove paused sandboxes that you no longer need.

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

  await Sandbox.kill(sandboxId)
  ```

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

  Sandbox.kill(sandbox_id)
  ```
</CodeGroup>

## Persistence vs snapshots

Persistence is for continuing the same sandbox later. Use it when you care about the exact sandbox ID and current running state.

Snapshots are for creating reusable saved states. Use a snapshot when you want to start one or more new sandboxes from the same captured filesystem and memory state.

For reusable states, see [Sandbox Snapshot](/guides/sandbox-snapshot).

## Network

If you pause a sandbox that has a running service, the service becomes inaccessible from outside the sandbox and any connected clients are disconnected. After you resume the sandbox, the service becomes accessible again, but clients must reconnect.
