Persistent memory

Every Cast agent has a persistent memory volume that’s mounted into the container at /app/agent/memory/. The agent can read and write files there; the volume survives deploys, upgrades, and restarts.

What’s in the volume

By convention, agents use the volume to store:

The volume is a regular filesystem mount, so the agent can use plain file I/O. There’s no special API.

How it’s mounted

ProviderMount targetNotes
Docker (local)cast-<name> named volumemanaged by docker volume
Railwaypersistent volume attached to the serviceprovisioned on first deploy
Flyvolume attached to the appprovisioned on first deploy
DigitalOceandirectory inside the droplet’s host filesystemmounted into the container
DigitalOcean MicroVMMicroVM disk at /app/agent/memorysurvives pause and resume. Upgrade copies it to the replacement MicroVM when it is 8 MiB or smaller
Spritespersistent directory inside the spritemanaged by Sprites

The volume is keyed by the agent name, not the deployment SHA. So when you cast upgrade <sha> --version 1.7, the new container reattaches the same volume and the agent’s memories are intact.

The volume_config field

Cast records the volume configuration in the deployments table (volume_id, volume_config columns) so it can be re-attached on upgrade. On cast shutdown the volume is not deleted by default — shutting down a deployment doesn’t forget the agent’s memory.

To destroy the volume along with the deployment, pass --destroy-volume to cast shutdown (or use --force and answer the confirmation).

How the runtime exposes the volume

Inside the container, the volume is mounted at /app/agent/memory/. The runtime Python module reads CAST_AGENT_PATH to know where the agent lives and joins memory/ to that path.

If the agent wants to use the memory from a custom tool:

from pathlib import Path
import os

MEMORY = Path(os.environ['CAST_AGENT_PATH']) / 'memory'

@tool
def remember_about_user(key: str, value: str) -> str:
    """Save a fact about the user to long-term memory."""
    MEMORY.mkdir(parents=True, exist_ok=True)
    (MEMORY / 'user.md').write_text(f"- {key}: {value}\n", append=True)
    return "saved"

Inspecting the memory locally

# While a cast dev is running, the memory lives at:
ls ~/.cast/agents/<name>/memory/

# In a deployed container (Docker):
docker exec cast-<name> ls /app/agent/memory/

# In a deployed container (DigitalOcean, on-host):
docker exec -it cast-agent ls /app/agent/memory/

Backing up

Treat the volume like a database:

Resetting memory

cast shutdown <name> --destroy-volume
cast deploy <name> --provider <provider>

The agent starts fresh on the next deploy with no prior memories.