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:
- Long-term notes about the user (“prefers short replies”, “works in UTC”, etc.).
- Per-conversation summaries that the agent can pull into context.
- Cached responses to expensive lookups.
- Anything else the agent wants to remember.
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
| Provider | Mount target | Notes |
|---|---|---|
| Docker (local) | cast-<name> named volume | managed by docker volume |
| Railway | persistent volume attached to the service | provisioned on first deploy |
| Fly | volume attached to the app | provisioned on first deploy |
| DigitalOcean | directory inside the droplet’s host filesystem | mounted into the container |
| DigitalOcean MicroVM | MicroVM disk at /app/agent/memory | survives pause and resume. Upgrade copies it to the replacement MicroVM when it is 8 MiB or smaller |
| Sprites | persistent directory inside the sprite | managed 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:
cast git init+cast git pushfor code-level state.cast releasefor versioned snapshots.- For the memory volume itself, snapshot it with your provider’s
tooling (
docker volume create,fly volumes snapshots create, etc.) on whatever schedule makes sense for your agent.
Resetting memory
cast shutdown <name> --destroy-volume
cast deploy <name> --provider <provider>
The agent starts fresh on the next deploy with no prior memories.