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

# Migrate a Daytona command worker to Sailboxes

> Give this guide to your coding agent to migrate a Daytona v0.231 Python command worker to Sailboxes. It identifies the separate steps for terminals, mounted volumes, and preview URLs.

## Sailboxes vs. Daytona: CPU and memory billing

Sail charges lower CPU and RAM rates than Daytona. Sail charges \$0.015 per used vCPU-hour and \$0.008 per GiB-hour of RAM used. RAM usage includes the Linux filesystem cache. Daytona charges \$0.0504 per reserved vCPU-hour and \$0.0162 per reserved GiB-hour while the sandbox runs. Both platforms stop CPU and RAM charges during pause. Daytona still charges for reserved disk. Sail stops local disk charges. Separate Sail volumes still have storage charges. [Sail pricing](https://docs.sailresearch.com/sailboxes-pricing.md#rates) · [Daytona rates](https://www.daytona.io/pricing) · [Daytona billing states](https://www.daytona.io/docs/en/billing/)

## Create the Sailbox

Install the [Sail Python SDK](https://docs.sailresearch.com/reference/python-sdk.md) on the machine that runs your controller. Run `python -m pip install sail`. Sign in with `sail auth login`. Create one Sailbox per session. This example saves its ID in a local file. In your application, store the ID with the agent session.

```python theme={null}
from pathlib import Path
import sail

app = sail.App.find(name="migration-demo", mint_if_missing=True)
sb = sail.Sailbox.create(app=app, name="daytona-worker")
Path("sailbox-id.txt").write_text(sb.sailbox_id)
```

## Transfer files

Daytona’s `fs.upload_file(data, path)` takes the file contents first. Sail’s `fs.write(path, data)` takes the destination first. Run this code from the directory that contains `worker.py` and `job.json`. The example worker reads `/tmp/job.json` and writes `/tmp/result.json` inside the Sailbox. Use the paths your worker needs.

```python theme={null}
sb.fs.write("/tmp/worker.py", Path("worker.py").read_bytes())
sb.fs.write("/tmp/job.json", Path("job.json").read_bytes())
```

Before you close the old workspace, copy uncommitted changes and any files you need. Export mounted volumes separately.

## Run your existing worker

Replace `sandbox.process.exec()` with `sb.run()`. Read the output from `result.stdout`. Set the working directory and environment for each command. A new shell does not keep the previous shell’s `cd` or `export` settings.

```diff theme={null}
- response = sandbox.process.exec("python3 /tmp/worker.py")
- print(response.result)
+ result = sb.run(["python3", "/tmp/worker.py"], check=True)
+ print(result.stdout)
```

Set up interactive terminals and previews separately. For a preview, configure the listener and access policy. Update the preview URL in your frontend.

## Reconnect after sleep

An idle Sailbox [sleeps automatically by default](https://docs.sailresearch.com/sailboxes-autosleep). Use the saved ID to find the same Sailbox. Read the result file. This operation wakes a sleeping Sailbox.

```python theme={null}
from pathlib import Path
import sail

sb = sail.Sailbox.get(Path("sailbox-id.txt").read_text().strip())
print(sb.fs.read("/tmp/result.json").decode())
```

Sleep preserves files and memory. [Termination deletes the Sailbox.](https://docs.sailresearch.com/sailboxes-lifecycle.md)

## Check the worker output

Run your worker with the same input on Daytona and on Sail. Compare the command output and the files from both runs.
