# Memory

Memory is a store of notes that workers read and write from task to task, with every change kept.

A task starts fresh. Memory is how a worker carries what it learned from one task to the next. It is a store of short notes at paths, like a small folder of text files. A worker reads the notes when a task starts, writes new ones as it works, and the next task finds them.

Memory uses Claude Managed Agents' words and shapes: a memory store holds notes, and every change to a note is saved as a version. This page explains stores, notes, which stores a task reads, how history is kept, and dreams, which tidy a store up.

## Stores and notes

A **memory store** is a named set of notes. Its id starts with `memstore_`. It has a `name` of 1 to 255 characters, a `description` of up to 1,024 characters, labels in `metadata` (up to 16 keys), and an `archived_at` that is `null` while the store is in use.

A **note** is text at a path. Its id starts with `mem_`. A folder in a listing, a `memory_prefix`, is only a path that ends with `/`, and it has no id.

| Part of a note | Rule |
| --- | --- |
| `path` | Starts with `/`, such as `/people/sam.md`. At most 1,024 UTF-8 bytes. No empty part, `.` or `..` between the slashes. |
| `content` | 0 to 102,400 UTF-8 bytes. An empty string makes an empty note. |
| `content_sha256` | The SHA-256 of the bytes you sent. |
| `content_size_bytes` | The size of the note. |
| `memory_version_id` | The newest version of the note. |

A store holds up to 10,000 notes. These rules apply to every write:

- **No two notes may collide on a path.** `/notes` and `/notes/todo.md` cannot both be notes: a note at the same path, at a folder above it or inside it is `409` with `error.type` `memory_path_conflict_error`.
- **No saved passwords.** A note whose text holds a saved password is refused with `400`.
- **No writes to an archived store.** That is `400`.

To change a note only if nobody else has, send a `precondition` of `{ "type": "content_sha256", "content_sha256" }` with the change. If the note no longer has that text, the answer is `409` with `error.type` `memory_precondition_failed_error`. A retry of an update that already landed answers `200` even though its hash is stale. Delete takes the same check as `expected_content_sha256` in the query.

A listing of notes takes `path_prefix`, `depth` (`0` or `1`) and `view`. In the `basic` view, `content` is `null`. The `full` view returns the text. A listing holds up to 1,000 notes a page, or 20 with `view=full`.

## Which stores a task reads

Every task has a worker's own store. Each worker has one, always read and written, and it does not count toward the workspace's limit of shared stores. A task may also read other stores:

- Name them in `resources` when you give the task, as `{ "type": "memory_store", "memory_store_id", "access", "instructions" }`. With any named, the task reads only those, and at most 8.
- Name none, and the task reads the stores attached to its worker.

`access` is `read_write` (the default) or `read_only`. `instructions`, up to 4,096 characters, tell the worker how to use that store.

A task freezes its stores when it is made. A later rename of a store does not reach a task that is already at work, and a task's stores never change after it is made.

The worker sees its stores as folders on the computer, one for each store, under the task's own root: `<workspace>/.little-worker/tasks/<task_id>/memory/<short name>/`. On the Linux computer, `<workspace>` is `/data/workspace`. A Mac does not make these folders yet. Every task also gets memory tools and a short memory section in its context, so the worker can reach its notes without the folders.

## Who changed a note

Every change to a note saves a **memory version**. Its id starts with `memver_`. A version has an `operation`, which is `created`, `modified` or `deleted`, and the note's path and text as they were. A `deleted` version has no text.

`created_by` says who made the change:

| `created_by.type` | Who |
| --- | --- |
| `task_actor`, with `task_id` | A worker, writing in one of its tasks. |
| `api_actor`, with `api_key_id` | A key, through this API. |
| `user_actor`, with a `user_` id | A person, in the app. The id is the same on every device. |
| `null` | The service itself, or a worker writing outside a task. |

List versions with `GET /memory_stores/{memory_store_id}/memory_versions`, newest first. Filter by `memory_id`, `operation`, `task_id`, `api_key_id`, or `created_at[gte]` and `created_at[lte]`. A page is 20 by default and at most 100.

A version can be redacted. Redacting empties its path and text but keeps who made the change and when. The newest version of a note that still exists cannot be redacted: that is `409`.

### How long versions are kept

Versions are kept for 30 days after they are written. The two newest versions of a note that still exists are always kept, whatever their age, so a note that rarely changes can keep history longer. Versions of a deleted note, and redacted versions, follow the same rule. It is the same on every plan. A core on your own computer keeps every version.

To keep memory history longer, export the versions through the API before they go.

## Archive and delete

- **Archive** a store with `POST /memory_stores/{memory_store_id}/archive`. It is one way: an archived store can only be read. It frees its place under the workspace limit.
- **Delete** a store with `DELETE /memory_stores/{memory_store_id}`. The store, its notes and its versions are removed. A worker's own store cannot be deleted: that is `409`.

A workspace keeps up to 1,000 live shared stores. A worker's own store does not count, and archiving a store frees its place. One more is `400`.

## Dreams

A dream cleans up a memory store. It reads one store, and up to 100 tasks to learn from, and writes a tidier store. A dream runs as a task: `task_id` names it, and you read its events with the task routes.

Make one with `POST /dreams`:

- `inputs` holds exactly one `{ "type": "memory_store", "memory_store_id" }` and at most one `{ "type": "tasks", "task_ids" }` with 1 to 100 tasks.
- `model` is a model id, or `{ "id" }`. Speed `fast` is `400`.
- `instructions`, up to 4,096 characters, guide the dream.
- `output_behavior` is `{ "type": "create_new" }`, the default, or `{ "type": "update_existing", "memory_store_id" }` with the input store.

A dream starts `pending` and then moves through its `status`: `pending`, `running`, and then `completed`, `failed` or `canceled`. `outputs` names the store with the result once the dream starts. `usage` counts its tokens, and `error` and `ended_at` are set when it ends.

`POST /dreams/{dream_id}/cancel` stops a dream. One that ended `completed` or `failed` is `400`. `POST /dreams/{dream_id}/archive` archives one that has ended, and it then leaves the list. A `pending` or `running` dream is `400`.

A dream that fails has an `error.type`:

| `error.type` | When it happens |
| --- | --- |
| `input_memory_store_too_large` | The input store holds more than 10 MiB of notes. The dream fails as it is made, with no task and no output store. |
| `memory_store_org_limit_exceeded` | The `create_new` copy would pass the workspace's 1,000 live shared stores. It fails as it is made. |
| `input_memory_store_unavailable` | The input store was archived or deleted while the dream ran. Its task is withdrawn. |
| `input_session_unavailable` | A task it reads was deleted while it ran. |
| `timeout` | It ran past 12 hours. |
| `internal_error` | Its task stopped with an error. |

## Limits

| What | Limit |
| --- | --- |
| Notes in a store | 10,000 |
| A note | 102,400 UTF-8 bytes |
| A path | 1,024 UTF-8 bytes |
| Store name | 255 characters |
| Store description | 1,024 characters |
| Stores a task reads | Its own, and up to 8 named in `resources` |
| `instructions` for a store | 4,096 characters |
| Live shared stores in a workspace | 1,000 |
| A dream's input | One store of at most 10 MiB, and up to 100 tasks |
| A dream's time | 12 hours |
| Memory versions | 30 days, and the two newest of each note |

## Next steps

- [Tasks](/concepts/tasks): how a task is given its stores in `resources`.
- [Routines](/concepts/routines): hand a store to every task a routine makes.
- [Files](/concepts/files): the other thing a task may be given to work with.
