import Image from "next/image";
import diagram from '@/images/diagram.svg'

# Sandbox persistence

<Note>
Sandbox persistence is currently in public beta:
1. Consider [some limitations](#limitations-while-in-beta).
2. The persistence is free for all users during the beta.
</Note>

The sandbox persistence allows you to pause your sandbox and resume it later from the same state it was in when you paused it.

This includes not only state of the sandbox's filesystem but also the sandbox's memory. This means all running processes, loaded variables, data, etc.

## Sandbox State Transitions

Understanding how sandboxes transition between different states is crucial for managing their lifecycle effectively. Here's a diagram showing the possible state transitions:


<div className="flex items-center justify-center">
    <Image className='rounded mx-auto' src={diagram} alt="Sandbox State Transitions" width="250" height="250" />
</div>

### State descriptions

- **Running**: The sandbox is actively running and can execute code. This is the initial state after creation.
- **Paused**: The sandbox execution is suspended but its state is preserved.
- **Killed**: The sandbox is terminated and all resources are released. This is a terminal state.

### Changing sandbox's state

<CodeGroup>
```js
import { Sandbox } from '@e2b/code-interpreter'

const sandbox = await Sandbox.create() // Starts in Running state

// Pause the sandbox
await sandbox.betaPause() // Running → Paused

// Resume the sandbox
await sandbox.connect() // Running/Paused → Running

// Kill the sandbox (from any state)
await sandbox.kill() // Running/Paused → Killed
```

```python
from e2b_code_interpreter import Sandbox

sandbox = Sandbox.create()  # Starts in Running state

# Pause the sandbox
sandbox.betaPause()  # Running → Paused

# Resume the sandbox
sandbox.connect()  # Running/Paused → Running

# Kill the sandbox (from any state)
sandbox.kill()  # Running/Paused → Killed
```
</CodeGroup>

## Pausing sandbox
When you pause a sandbox, both the sandbox's filesystem and memory state will be saved. This includes all the files in the sandbox's filesystem and all the running processes, loaded variables, data, etc.

<CodeGroup>
```js
import { Sandbox } from '@e2b/code-interpreter'

const sbx = await Sandbox.create()
console.log('Sandbox created', sbx.sandboxId)

// Pause the sandbox
// You can save the sandbox ID in your database to resume the sandbox later
await sbx.betaPause() // $HighlightLine
console.log('Sandbox paused', sbx.sandboxId) // $HighlightLine
```
```python
from e2b_code_interpreter import Sandbox

sbx = Sandbox.create()
print('Sandbox created', sbx.sandbox_id)

# Pause the sandbox
# You can save the sandbox ID in your database to resume the sandbox later
sbx.beta_pause() # $HighlightLine
print('Sandbox paused', sbx.sandbox_id) # $HighlightLine
```
</CodeGroup>


## Resuming sandbox
When you resume a sandbox, it will be in the same state it was in when you paused it.
This means that all the files in the sandbox's filesystem will be restored and all the running processes, loaded variables, data, etc. will be restored.

<CodeGroup>
```js
import { Sandbox } from '@e2b/code-interpreter'

const sbx = await Sandbox.create()
console.log('Sandbox created', sbx.sandboxId)

// Pause the sandbox
// You can save the sandbox ID in your database to resume the sandbox later
await sbx.betaPause()
console.log('Sandbox paused', sbx.sandboxId)

// Connect to the sandbox (it will automatically resume the sandbox, if paused)
const sameSbx = await sbx.connect() // $HighlightLine
console.log('Connected to the sandbox', sameSbx.sandboxId) // $HighlightLine
```
```python
from e2b_code_interpreter import Sandbox

sbx = Sandbox.create()
print('Sandbox created', sbx.sandbox_id)

# Pause the sandbox
# You can save the sandbox ID in your database to resume the sandbox later
sbx.beta_pause()
print('Sandbox paused', sbx.sandbox_id)

# Connect to the sandbox (it will automatically resume the sandbox, if paused)
same_sbx = sbx.connect() # $HighlightLine
print('Connected to the sandbox', same_sbx.sandbox_id) # $HighlightLine
```
</CodeGroup>

## Listing paused sandboxes
You can list all paused sandboxes by calling the `Sandbox.list` method and supplying the `state` query parameter.
More information about using the method can be found in [List Sandboxes](/docs/sandbox/list).

<CodeGroup>
```js
import { Sandbox, SandboxInfo } from '@e2b/code-interpreter'

// List all paused sandboxes
const paginator = Sandbox.list({ query: { state: ['paused'] } }) // $HighlightLine

// Get the first page of paused sandboxes
const sandboxes = await paginator.nextItems() // $HighlightLine

// Get all paused sandboxes
while (paginator.hasNext) {
  const items = await paginator.nextItems()
  sandboxes.push(...items)
}
```
```python
# List all paused sandboxes
from e2b_code_interpreter import Sandbox, SandboxQuery, SandboxState

paginator = Sandbox.list(SandboxQuery(state=[SandboxState.PAUSED])) # $HighlightLine

# Get the first page of paused sandboxes
sandboxes = paginator.next_items() # $HighlightLine

# Get all paused sandboxes
while paginator.has_next:
  items = paginator.next_items()
  sandboxes.extend(items)
```
</CodeGroup>

## Removing paused sandboxes

You can remove paused sandboxes by calling the `kill` method on the Sandbox instance.

<CodeGroup>
```js
import { Sandbox } from '@e2b/code-interpreter'

const sbx = await Sandbox.create()
console.log('Sandbox created', sbx.sandboxId)

// Pause the sandbox
// You can save the sandbox ID in your database to resume the sandbox later
await sbx.betaPause()

// Remove the sandbox
await sbx.kill() // $HighlightLine

// Remove sandbox by id
await Sandbox.kill(sbx.sandboxId) // $HighlightLine
```
```python
from e2b_code_interpreter import Sandbox

sbx = Sandbox.create()

# Pause the sandbox
sbx.beta_pause()

# Remove the sandbox
sbx.kill() # $HighlightLine

# Remove sandbox by id
Sandbox.kill(sbx.sandbox_id) # $HighlightLine
```
</CodeGroup>

## Sandbox's timeout
When you connect to a sandbox, the sandbox's timeout is reset to the default timeout of an E2B sandbox - 5 minutes.

You can pass a custom timeout to the `Sandbox.connect()`/`Sandbox.connect()` method like this:

<CodeGroup>
```js
import { Sandbox } from '@e2b/code-interpreter'

const sbx = await Sandbox.connect(sandboxId, { timeoutMs: 60 * 1000 }) // 60 seconds
```
```python
from e2b_code_interpreter import Sandbox

sbx = Sandbox.connect(sandbox_id, timeout=60) # 60 seconds
```
</CodeGroup>


### Auto-pause (beta)

**Note: Auto-pause is currently in beta and available through `Sandbox.betaCreate()`/`Sandbox.beta_create()` method.**

Sandboxes can now automatically pause after they time out. When a sandbox is paused, it stops consuming compute but preserves its state. The default inactivity timeout is 10 minutes. You can change the timeout by passing the `timeoutMs`/`timeout` parameter to the `Sandbox.connect()`/`Sandbox.connect()` method.

<CodeGroup>
```js
import { Sandbox } from '@e2b/code-interpreter'

// Create sandbox with auto-pause enabled (Beta)
const sandbox = await Sandbox.betaCreate({
    autoPause: true, // Auto-pause after the sandbox times out
    timeoutMs: 10 * 60 * 1000 // Optional: change the default timeout (10 minutes)
})
```
```python
from e2b_code_interpreter import Sandbox
# Create sandbox with auto-pause enabled (Beta)
sandbox = Sandbox.beta_create(
    auto_pause=True  # Auto-pause after the sandbox times out
    timeout=10 * 60, # Optional: change the default timeout (10 minutes)
)
```
</CodeGroup>

The auto-pause is persistent, meaning that if your sandbox resumes and it times out, it will be automatically paused again.

If you `.kill()` the sandbox, it will be permanently deleted and you won't be able to resume it.

## Network
If you have a service (for example a server) running inside your sandbox and you pause the sandbox, the service won't be accessible from the outside and all the clients will be disconnected.
If you resume the sandbox, the service will be accessible again but you need to connect clients again.


## Limitations while in beta
- Pausing a sandbox takes about 4 seconds per 1 GiB of RAM
- Resuming a sandbox takes about 1 second
- Sandbox can be used up to 30 days
  - After 30 days from the initial sandbox create call, the data may be deleted and you will not be able to resume it. Attempting to resume a sandbox that was deleted or does not exist will result in the `NotFoundError` in the JavaScript SDK or the `NotFoundException` in the Python SDK
