#Automatic recovery
<subtitle>Have a suspended sandbox resume running automatically upon access or SDK action. </subtitle>

Many workloads do not require the sandbox to be running all the time, but once a request or operation comes in, the sandbox should be able to continue working directly. Automatic recovery is used to handle this scenario: when the suspended sandbox receives activity, the system automatically wakes up the sandbox, and the business code does not need to check in advance or manually manage the sandbox status.

Automatic recovery is based on the lifecycle capabilities of [sandbox persistence](/docs/agent-sandbox/sandbox/persistence.md). When enabled, the sandbox can automatically pause after a timeout and resume when subsequent activity arrives.

> Automatically resume dependency-suspended sandboxes. A suspended sandbox will occupy persistent storage and be billed according to persistent storage rules. For detailed billing methods, please refer to [Billing Instructions](/docs/agent-sandbox/product/fee.md).

## Configure automatic recovery

Set `lifecycle` when creating a sandbox to control the actions after the sandbox times out, and whether the paused sandbox automatically resumes when activity is received.

```python
from ucloud_sandbox import Sandbox

sandbox = Sandbox.create(
    timeout=10 * 60,
    lifecycle={
        "on_timeout": "pause",
        "auto_resume": True, # Automatically resume when activity is received
    },
)
```

### Lifecycle options

`lifecycle` supports the following common configurations:

| Configuration item | Value | Description |
| --- | --- | --- |
| `on_timeout` | `"kill"` | Default behavior. The sandbox is destroyed after reaching the timeout |
| `on_timeout` | `"pause"` | The sandbox automatically pauses after reaching the timeout period and retains the file system and memory status |
| `auto_resume` | `False` | Default behavior. The paused sandbox will not be automatically restored and requires manual connection |
| `auto_resume` | `True` | The paused sandbox automatically resumes when it receives activity. Typically used with `on_timeout: "pause"` |

If `auto_resume` is not enabled, a suspended sandbox can still be resumed manually via `Sandbox.connect()`.

```python
from ucloud_sandbox import Sandbox

same_sandbox = Sandbox.connect("your-sandbox-id")
```

## Timeout after automatic recovery

After the sandbox is automatically restored, the timeout period will be calculated again. The timeout after recovery is at least **5 minutes**; if a longer `timeout` was set when the sandbox was created, the longer value will be inherited.

For example, to set a 2-minute timeout when creating a sandbox:

1. The sandbox will automatically pause after running for 2 minutes.
2. When subsequent activities arrive, the sandbox will be automatically restored.
3. Use a 5 minute timeout after recovery as 5 minutes is the minimum timeout after automatic recovery.
4. If there is no new activity and the refresh times out, the sandbox will pause again after 5 minutes.

If you set a 1-hour timeout when creating the sandbox, the timeout after auto-recovery is also 1 hour because it exceeds the 5-minute minimum.

This cycle repeats after each automatic recovery. Lifecycle configuration persists across pauses and resumes.

> You can call `set_timeout()` to modify the timeout after the sandbox is restored. For more instructions, please refer to [Sandbox Lifecycle](/docs/agent-sandbox/sandbox/lifecycle.md).

## Which activities will trigger automatic recovery?

Automatic recovery is triggered by sandbox activity, including HTTP traffic and SDK operations.

Common triggering methods include:

- `sandbox.commands.run(...)`
- `sandbox.files.read(...)`
- `sandbox.files.write(...)`
- Open the public URL of a service within the sandbox, or send a request to a service running within the sandbox

If the sandbox is in a suspended state and was created with `lifecycle.auto_resume` enabled, the next supported operation will automatically resume the sandbox. At this time, there is no need to call `Sandbox.connect()` first.

## Example: Read file after pause

The following example writes to a file, pauses the sandbox, and then reads the file. Read operations trigger automatic recovery.

```python
from ucloud_sandbox import Sandbox

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

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

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

## Example: Automatically resume web services

Automatic recovery is well suited for web serving and preview environments. After the sandbox is suspended, if there is an HTTP request to access the service in the sandbox, the sandbox will automatically resume and process the request.

The following example starts a simple HTTP service and gets its public URL. You can obtain the public network access domain name corresponding to the specified port through `get_host()`.

```python
from ucloud_sandbox 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)

# After the sandbox times out and is suspended, accessing this URL will automatically resume the sandbox.
print(f"Preview address: https://{host}")
```

## Clean up the sandbox

The automatic recovery configuration will continue to take effect: after the sandbox is restored, if it times out again, it will still be automatically suspended again. As long as there are subsequent activities coming, the sandbox will cycle between Running and Paused.

If the sandbox is no longer needed, call `.kill()`. A destroyed sandbox cannot be restored again.

```python
sandbox.kill()
```
