---
title: How to Use Persistent Workspaces with Harness Runtime (public)
description: Create a persistent workspace, attach it to a Harness Runtime session, and reuse its files in a new session after you remove the old one.
product: Managed Agents
url: https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/use-persistent-workspaces/
last_updated: "2026-11-05"
---

> **For AI agents:** The documentation index is at [https://docs.digitalocean.com/llms.txt](https://docs.digitalocean.com/llms.txt). Markdown versions of pages use the same URL with `index.html.md` in place of the HTML page (for example, append `index.html.md` to the directory path instead of opening the HTML document).

# How to Use Persistent Workspaces with Harness Runtime (public)

DigitalOcean Harness Runtime provides managed, hardware-isolated microVM sandboxes with built-in tools such as Chromium to run harnesses and execute arbitrary code. Rich lifecycle APIs preserve conversational history and working state across sessions, letting you pause, resume, and fork work to control costs and adapt to the nonlinear nature of agentic workflows. Scale complete agents such as Claude Code or use sandboxes independently for code execution, all through the same service. See [What You Can Build](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/details/what-you-can-build/index.html.md) for example use cases.

A persistent workspace is a saved set of files with its own ID. Inside a session, it is the `/workspace` folder. When you remove the session or [take a checkpoint](#checkpoint-a-session-with-a-workspace), Harness Runtime saves the files and keeps them. A new session that uses the same workspace starts with the same files.

Use a persistent workspace to keep an agent’s files when you remove a session, for example to [move the agent to a new template](#upgrade-a-session-to-a-new-template). Persistent workspaces are free during public preview. For feature limits, see [Persistent Workspaces Limits](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/details/limits/index.html.md#persistent-workspaces).

**Note**:

  Persistent workspaces are in [public preview](https://docs.digitalocean.com/platform/product-lifecycle/index.html.md#public-preview) and are free during public preview. They are enabled per team, so you do not opt in from the **Feature Preview** page. If they are not enabled for your team, every workspace request, and any session create that names a `workspace_id`, returns `403`.

## How Persistent Workspaces Work

- A workspace is attached to one session at a time, and a session has at most one workspace.
- You attach a workspace when you create the session. You cannot attach one to a running session.
- The workspace always mounts at `/workspace`.
- The size is fixed when you create the workspace (1 to 100 GiB), and resizing is not currently supported. Size it for the files you need to keep. The template provides the rest.
- Removing a session never deletes its workspace. Only deleting the workspace removes its files.
- Harness Runtime saves the workspace when you remove the session or [take a checkpoint](#checkpoint-a-session-with-a-workspace).

Inside the session, the agent sees the following:

- `/workspace` is its own filesystem. `df /workspace` shows its size and use, and `df /` shows the rest of the session.
- Moving a file between `/workspace` and the rest of the session copies it.
- Writing past the size limit fails with the usual `No space left on device` error and does not affect the rest of the session.
- Permissions, file locks, and `fsync` work as on a local disk, so databases such as SQLite work unchanged.

A workspace is always in one of the following states:

| State | Meaning |
|---|---|
| `AVAILABLE` | Ready to attach to a new session. |
| `ATTACHING` | A session is being created with the workspace. |
| `ATTACHED` | A session is using the workspace. |
| `RELEASING` | The session was removed and the files are being saved. This can take a few minutes. |
| `FAILED` | The workspace could not be saved or created. It keeps its last successful save. See [Troubleshoot Workspace Errors](#troubleshoot-workspace-errors). |
| `DELETING` | A delete is in progress. |

New states might be added over time, so treat any state you do not recognize as unavailable.

## Create a Workspace

Create a workspace with a size limit. The name is an optional label and does not need to be unique:

```shell
doctl harness-runtime workspace create --size-limit-gib 10 --name notes
```

The command prints the workspace ID. Use the ID, not the name, in every other command.

`create` sends an idempotency key so that a retry does not create a second workspace. If a script reruns the whole command, pass your own key with `--idempotency-key <key>`.

Show, list, and delete workspaces with the following commands:

```shell
doctl harness-runtime workspace get <workspace-id>
doctl harness-runtime workspace list --state AVAILABLE
doctl harness-runtime workspace delete <workspace-id>
```

`delete` is permanent. You can delete a workspace only when it is `AVAILABLE` or `FAILED`. At a terminal, `delete` asks you to confirm. Use `--force` to skip the prompt.

## Attach a Workspace to a Session

A workspace is chosen for each session and is not part of an agent manifest. To attach one, save the manifest as an Agent Config, then create the session from the config with `--workspace`:

```shell
doctl harness-runtime config create --spec agents.yaml --name reviewer
doctl harness-runtime create --from-config reviewer --name review-1 --workspace <workspace-id>
```

`--workspace` also works with `launch --from-config`. It does not work with a manifest file, `--harness`, or `--template`.

Files the agent writes to `/workspace` are saved when you remove the session or [take a checkpoint](#checkpoint-a-session-with-a-workspace).

## Checkpoint a Session with a Workspace

Take a [checkpoint](https://docs.digitalocean.com/products/managed-agents/agent-harness-runtime/how-to/checkpoint-fork-rollback-sessions/index.html.md) to save the files in `/workspace` without removing the session. Fork and rollback are not available for a session with a persistent workspace, so you cannot return to that checkpoint. Files written after your last checkpoint are not guaranteed to be in a new session.

```shell
doctl harness-runtime checkpoint create <your-session-name>
```

Removing a session also saves the files in `/workspace`, so take a checkpoint or remove the session before you rely on a workspace being up to date. To check when the workspace was last saved, run `doctl harness-runtime workspace get <workspace-id>` and look at `last_saved_at`.

## Reuse a Workspace in a New Session

Remove the session, wait until the workspace is `AVAILABLE` again, and create a new session with the same workspace:

```shell
doctl harness-runtime remove review-1
doctl harness-runtime workspace get <workspace-id>
doctl harness-runtime create --from-config reviewer --name review-2 --workspace <workspace-id>
```

If you create the new session while the workspace is `RELEASING`, the request fails with a conflict. Run `workspace get` again until the state is `AVAILABLE`, then retry.

## Upgrade a Session to a New Template

A workspace outlives the session and its template, so you can move an agent to a new template without losing its files:

1. Build the new template. Make sure it runs the agent as the same user and group IDs as the old template. Files in a workspace keep the numeric user and group ID of the user that wrote them, so otherwise the new session cannot modify files the old session wrote.
2. Remove the session with `doctl harness-runtime remove <name>`.
3. Run `doctl harness-runtime workspace get <workspace-id>` until the state is `AVAILABLE`.
4. Create a new session from a config that uses the new template, with the same `--workspace <workspace-id>`.

The new session starts with the files the old session saved.

## Use the API or an SDK

The workspace endpoints are:

| Request | Description |
|---|---|
| `POST /v2/agents/workspaces` | Create a workspace. |
| `GET /v2/agents/workspaces` | List workspaces. Supports `page_size`, `page_token`, and `state`. |
| `GET /v2/agents/workspaces/{workspace_id}` | Get one workspace. |
| `DELETE /v2/agents/workspaces/{workspace_id}` | Delete a workspace permanently. |

To create a workspace, send a JSON body with `size_limit_gib` and an optional `name`. Add an `Idempotency-Key` header (up to 255 characters) to make retries safe. Within 24 hours, the same key and body returns the existing workspace, and the same key with a different body returns `422`. A list can return fewer results than `page_size`, so keep paging until `next_page_token` is empty.

To attach a workspace, add `workspace_id` to the body of `POST /v2/agents/sessions` along with `config_id`:

```json
{
  "name": "review-2",
  "config_id": "<config-id>",
  "workspace_id": "<workspace-id>"
}
```

A manifest that contains `workspace_id` is rejected with `400`.

A workspace has the following fields: `workspace_id`, `name`, `state`, `attached_session_id`, `size_limit_gib`, `bytes_used`, `last_saved_at`, `created_at`, and `updated_at`. `bytes_used` is an estimate and can differ from the usage you see inside the session. `size_limit_gib` is a quota, so the filesystem total inside the session is slightly lower.

In `pydo`, use `client.agents.workspaces` and pass `workspace_id` to `create_from_config`:

```python
workspace = client.agents.workspaces.create(10, name="notes").workspace
session = client.agents.create_from_config(
    name="review-1", config_id=config_id, workspace_id=workspace.workspace_id
)
```

In `godo`, use `CreateWorkspace`, `ListWorkspaces`, `GetWorkspace`, and `DeleteWorkspace`, and set `WorkspaceID` on the create-session-from-config request.

## Troubleshoot Workspace Errors

| Error | Cause and fix |
|---|---|
| `403` workspaces are not enabled | Persistent workspaces are not enabled for your team. |
| `404` workspace not found | The ID is unknown, belongs to another team, or was deleted. Use the workspace ID, not its name. |
| `409` attached to another session | Remove the session that holds the workspace first. |
| `409` still being saved | The previous session was removed recently. Run `workspace get` until the state is `AVAILABLE` and retry. |
| `409` workspace save failed | The workspace is `FAILED`. See the next row. |
| Workspace is `FAILED` | Retry removing the session. If it stays `FAILED`, contact support before deleting it, because deleting is permanent. |
| `409` limit reached | Delete workspaces you no longer need. |
| `503` the workspace could not be released yet | Retry removing the session. |