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

# Daytona Runtime

> Run agents in Daytona Cloud sandboxes

Xum can run workspaces in [Daytona](https://www.daytona.io/docs) sandboxes. Each new Daytona workspace gets its own sandbox, and Xum connects to it over SSH through Daytona's SSH gateway. Builds, tests, and other agent commands use the sandbox's CPU and memory, not your machine's. Under the hood a Daytona workspace is an [SSH workspace](https://xum.cdr.dev/runtime/ssh.md), so `XUM_RUNTIME` is `ssh`.

## Requirements

* A Daytona account and an API key from the Daytona dashboard
* `ssh` installed on the machine running Xum
* A Linux snapshot (or Daytona's default) with git and your toolchain. Xum runs Linux shell commands over SSH, so it does not offer Windows snapshots, and refuses one before it creates a sandbox.

## Set up access

1. Open **Settings > Runtimes** and find the **Daytona** row.
2. Paste your API key and click **Save**.
3. Click **Test connection**.

Xum stores the key in `~/.xum/daytona.json` (under `XUM_ROOT` when it is set) with file mode `0600`. The settings page never shows a saved key again: to change it, enter a new one, or click **Remove key**.

Without a saved key, Xum uses `DAYTONA_API_KEY` from its own environment. A saved key wins over the environment.

For a self-hosted (BYOC) Daytona install, set `DAYTONA_API_URL` in the environment of the Xum server. It must use `https://`, so that no one on the network can read the API key; `http://` works only for a loopback host (`localhost`, `127.0.0.1` or `::1`). A `DAYTONA_API_URL` that is not accepted keeps Daytona unavailable until you fix it; Xum never sends the key to another deployment instead. `DAYTONA_TARGET` picks a default region; without it, Daytona uses its default.

> [!WARNING]
>
> Do not put your Daytona API key in **Secrets**. Xum passes secrets to agent turns and terminals,
> so an agent could read the key and create or delete sandboxes in your organization.

## Sizes

| Size | vCPU | Memory | Disk |
| - | - | - | - |
| Small | 2 | 4 GiB | 10 GiB |
| Medium | 4 | 8 GiB | 20 GiB |
| Large | 8 | 16 GiB | 40 GiB |

Small is the default. Xum offers only these sizes, which keeps costs predictable.

## Create a workspace

1. In the new-workspace controls, choose **Daytona** as the runtime.
2. Pick a snapshot and a size.
3. Xum creates the sandbox, waits until it starts, clones the project, and runs the [init hook](https://xum.cdr.dev/hooks/init.md).

Xum labels each sandbox it creates with `xum.instance`, `xum.workspaceId`, and `xum.project`. If Daytona rejects the size for a snapshot, Xum creates the sandbox at the snapshot's size and then resizes it.

Xum uses only sandboxes it creates: a workspace cannot use an existing sandbox.

## Lifecycle

| Xum event | Daytona action |
| - | - |
| A turn starts | Start the sandbox if it is stopped or archived (waits up to 3 minutes) |
| An agent is streaming or a job runs | Report activity every minute, so Daytona does not stop the sandbox |
| Idle | Daytona stops the sandbox after 30 minutes and archives it after 1 day stopped |
| Sub-agent with a forked workspace | A new worktree in the same sandbox, not a second sandbox |
| Archive | Delete the sandbox at once, without a check for uncommitted work |
| Delete | Delete the sandbox; a running one is first checked for uncommitted or unpushed work |
| Opening a workspace | Background git and PR status checks do not start the sandbox; they wait until it runs |
| Sandbox no longer exists | The workspace reports it; Xum does not recreate it |

Each sandbox belongs to the workspace that created it. Archiving or deleting that workspace deletes the sandbox, even while forks of it (sub-agent worktrees) still use it; **Settings > General > Remote box on archive** does not apply to Daytona. Unarchiving a workspace whose sandbox was deleted does not bring the sandbox back, so push or copy any work you need before you archive. An agent cannot archive the workspace that created a sandbox: it asks you to do it. Archiving or deleting a fork removes only its worktree and never stops or deletes the sandbox. Xum records the id of each sandbox it creates in the workspace's settings, and every Daytona request about the sandbox uses that id, so a sandbox that later gets the same name is never touched. Before Xum starts a sandbox, opens SSH access to it, or deletes it, it also checks that the sandbox carries this install's `xum.instance` label. A sandbox without it (for example one whose label was removed) is never used or deleted, and Xum notes it in its log.

A forced delete removes the workspace even when Daytona refuses to delete the sandbox; it then shows a warning that names the sandbox, which you delete in the Daytona dashboard.

Xum does not stop or delete sandboxes that no workspace uses (for example one whose delete failed); Daytona stops them after 30 minutes idle. Delete them in the Daytona dashboard.

## SSH setup

Xum writes the SSH settings for its sandboxes to `~/.xum/ssh/daytona.conf` and adds a managed block to the top of `~/.ssh/config` that includes it for hosts named `<sandbox-name>.xum--daytona`. The gateway's access token is the SSH user name; Xum keeps it in memory and gets it for one hour. When Xum brings a sandbox up for a turn or a terminal, it replaces a token that has less than 15 minutes left. Xum does not replace tokens in the background, so your own SSH clients can be refused after the hour until Xum uses the sandbox again. Xum revokes the token when it replaces it, when you change the Daytona settings, and when it deletes the sandbox. At startup, Xum takes over the tokens that an earlier run left in `daytona.conf`, so it can filter and revoke them too. Before each SSH command it reads the file again, in case that read failed at startup. When an SSH command to a running sandbox fails (for example the gateway refuses a token revoked outside Xum, or Daytona moved its gateway or changed its host keys), Xum reads the gateway settings from Daytona again, rewrites the SSH settings, gets a new token, and runs the command again once. Xum replaces any token it finds in SSH errors and logs with `<daytona-token>`; output of commands that you or an agent run in a terminal is not filtered.

Xum pins the gateway's host keys in `~/.xum/ssh/daytona_known_hosts` and refuses a gateway whose key does not match, with OpenSSH and with the built-in SSH2 transport alike. This holds for `xum server` too, which otherwise skips host key checks for SSH hosts.

Xum's own SSH connections to sandboxes read only `daytona.conf` (OpenSSH runs with `-F`), so nothing in your `~/.ssh/config` or in `/etc/ssh/ssh_config` applies to them: a `Host *` entry's `User`, `ProxyCommand`, `KnownHostsCommand`, forwards or `Match exec` never run for a sandbox, and neither does a system-wide proxy or jump host. The managed block in `~/.ssh/config` is for your own SSH clients, such as an editor's Remote-SSH, which do read your config. OpenSSH uses the first value it finds for each setting, and Xum keeps its block first in the file, so its settings win for sandboxes in those clients too: strict host key checking against the pinned keys, the token as the user name, no proxy or jump host, no agent or X11 forwarding, and `LogLevel QUIET`, because an ssh error message would print the token. Your other entries still apply to every other host. A `KnownHostsCommand` or `Match exec` line in your config still runs for sandboxes in your own clients, with the token as `%r`; scope such lines to the hosts that need them. OpenSSH adds up `RemoteForward` lines instead of keeping the first, so a `RemoteForward` in a `Host *` entry also opens a tunnel from the sandbox to your machine in those clients; scope it to the hosts that need it.

## Notes

* **Costs:** Daytona bills running sandboxes by size and time. Archive or delete workspaces you no longer need, and pick the smallest size that works.
* **CPU count:** `nproc` inside a sandbox reports the host's CPUs, not the sandbox's, so builds may start too many parallel jobs. Set job counts (for example `MAKEFLAGS=-j4`) in your snapshot or in the project's [`.xum/tool_env`](https://xum.cdr.dev/hooks/tools).
* User-level hooks and skills in a sandbox live under `~/.mux`, the same as on other SSH hosts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.