Skip to main content
Fleet separates persistence into three layers with distinct lifetimes and authorities. The commit boundary is a single durable event: POST /api/sessions/{session_id}/turns streams a Turn attempt, and only a successful commit advances Session history, publishes Artifact identity, and writes the Turn/Run/Checkpoint/Artifact rows atomically. For the sandbox and volume mechanics that sit under this model, see Daytona runtime.

The three persistence layers

Every later Run receives a fresh interpreter context. Workspace files and Postgres rows outlive Sandbox replacement independently.

Alembic-managed Postgres

The relational store is the canonical record. Domain repository interfaces live under src/fleet_rlm/persistence/, and Alembic owns the live schema. Runtime startup never applies migrations. Apply the head schema explicitly before serving traffic:
The managed profile requires FLEET_DATABASE_URL. Local SQLite is suitable for development only. Fleet runs under one deterministic local User + Workspace scope, so requests carry no Authorization header and there is no row-level security scoping to configure.

Committed Turn history

A Turn attempt is streamed through:
The response is the AI SDK UI message stream. On a successful commit, the Turn atomically writes to Turn, Run, Checkpoint, and Artifact tables in one transaction. A failed commit advances no Session history, publishes no Artifact identity, and still releases owned resources. Cancelled attempts persist a bounded tombstone:
  • The original user input.
  • One assistant message carrying only a cancelled data-status part.
  • Observed usage counters.
  • The closed text Turn cancelled.
Tombstones never carry reasoning, code, output, or Tool evidence. The full committed Session history stays host-side. The RLM reads it through the bounded read_session_history Tool rather than by loading transcripts into a prompt.

Session catalog

Sessions are owned by the local scope and addressed under /api/sessions (no /v1 prefix). There is no export endpoint. Backup is handled at the Postgres and Volume layers, not through an application-level dump.

Daytona Workspace Volume Scope

The Volume mount is fixed at /home/daytona/fleet, configured through [defaults.daytona] volume_mount_path. Fleet provisions only the namespaces it owns and leaves bundled Skills host-owned — they are not copied into the Volume.

Attachments and Artifacts

Attachments and Artifacts share the Volume Scope but move through very different lifecycles. Attachments. POST /api/attachments uploads durable bytes to Workspace Volume Scope before writing metadata, then stages the file for the referenced Runs. Attachment identity is public at upload time. Artifacts. A candidate lives privately in the Run scope until Turn Commit. The path is:
  1. The host-mediated create_artifact produces a private Run candidate.
  2. Verified bytes reach a UUID-unique durable path under artifacts/.
  3. Turn Commit atomically writes the Artifact row and publishes identity.
There is no POST /api/artifacts. Read paths are:
  • GET /api/artifacts/{artifact_id} — metadata.
  • GET /api/artifacts/{artifact_id}/content — verified bytes.
Failed metadata commits may leave GC-eligible orphan bytes behind, but never public rows.

Session Workspace files

Session Workspace files are immediate private state under the Session Volume path. Daytona exposes bounded operations against them:
  • List and read with pagination.
  • Append, in-place unique fragment edit, and whole-file replacement.
  • Strict delete for files and empty directories only. No recursion, no force flag.
Writes, appends, edits, and deletes accept optional SHA-256 preconditions and never follow symlinks. For write and append, checksum comparison and mutation execute inside one mounted Workspace agent operation with target locking and inode revalidation across I/O Sandboxes. Existing Workspace documents can be staged as private Artifact Candidates without resending bytes. Turn Commit remains the only publication boundary. Workspace files survive failed Runs and Sandbox replacement independently of the commit-gated result.json snapshot and the Artifact lifecycle.

The Files API surface

The Files API (/api/files*) always resolves the process-local Workspace. Callers cannot select a Workspace or address Daytona Volume, mount, Sandbox, Attachment, Artifact, Session, or Run identifiers.
  • No rename operation.
  • DELETE /api/files/content removes one file or one empty directory. Non-empty targets return 409.
  • PATCH /api/files/content requires the old text to occur exactly once. Absent or ambiguous matches return 409. The response returns the fresh checksum so callers can chain preconditions.
See HTTP API for the full request and response shapes.

Workspace Memory

Workspace Memory is separate workspace-wide immediate state, not Session history and not a Turn-commit record. It lives at a fixed path:
A pre-existing root MEMORIES.md migrates on first open without losing content. Session and Run state retain their nested paths below that root. The RLM accesses memory through a bounded Tool set:
  • read_workspace_memory
  • remember
  • list_memories
  • search_memories
  • edit_memory
  • forget
  • update_workspace_memory (back-compat alias)
Fleet injects a bounded workspace_memory tail digest of relevant plus newest records into each Turn’s session_context. The digest is capped at 4 KiB, so the RLM has recent context without needing a Tool call. The RLM may append a record only when the user explicitly asks to remember something. remember writes v3 records with a fresh id and up to 4 KiB of formatted UTF-8. Records are durable immediately. Reads return the newest complete records within a fixed 256 KiB byte budget, and the configured max_upload_bytes caps the whole memory file. Memory survives failed Runs and Sandbox replacement.

Interpreter context

Interpreter calls within one Run reuse a single context, so Python globals, imports, and helper functions persist across RLM iterations inside that Run. The context is volatile:
  • It never crosses Run boundaries.
  • Every later Run receives a fresh context.
  • It carries no durable state — anything meant to outlive the Run must reach the Volume or Postgres.

Backup and recovery

  • Postgres. Alembic head is the durable schema baseline. Use uv run alembic upgrade head for explicit deployment and uv run alembic check to verify.
  • Volume. Daytona Volume snapshots taken through the provider are the durable-state backup path for Workspace Memory, Session Workspace files, Attachments, and Artifact bytes.
  • No first-class export. Fleet does not ship an “export everything” command. Postgres and the Volume are the source of truth, backed up in place.

See also

Daytona runtime

Sandbox lifecycle, volume mount, and the host-callback bridge under this persistence model.

HTTP API

Session, Turn, Attachment, Artifact, and Files endpoint reference.

Configuration

FLEET_DATABASE_URL, [defaults.daytona] volume_mount_path, and related policy in config/fleet.toml.

Architecture

Where the three persistence layers sit inside the overall Fleet layering.
Last modified on August 13, 2026