> ## Documentation Index
> Fetch the complete documentation index at: https://graph.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage

> Plain files by default, abstracted for other backends

graph stores its runtime state as plain JSON and JSONL files under the data directory (`~/.local/share/graph/` by default). Zero setup, human-readable, and safe under concurrent `graph` processes.

## What's stored

| Data               | Purpose                                                      |
| ------------------ | ------------------------------------------------------------ |
| Threads & messages | conversation continuity (`--thread`), audit (`threads show`) |
| Tool shapes        | the [shape cache](/tools/shape-cache) that trains planning   |

## Layout

```text theme={null}
<data_dir>/threads/<id>/meta.json        thread metadata (title, timestamps, message count)
<data_dir>/threads/<id>/messages.jsonl   one message per line, in order
<data_dir>/shapes/<tool>.json            one cached shape per tool
```

Everything is directly inspectable with `cat` and `jq`, and `graph threads` / `graph shapes` render the same data from the CLI. Shape filenames percent-encode characters outside `[A-Za-z0-9_.-]`; the authoritative tool name lives inside the file.

## Concurrency

Multiple graph processes — parallel CI jobs, simultaneous one-shots — can share one `data_dir`:

* Whole files (`meta.json`, shapes) are written to a temp file and atomically renamed into place, so readers never observe a partial write.
* Message appends go through `O_APPEND` as a single write, serialized per thread by an advisory lock so metadata stays consistent with the log.
* Shape writes are last-writer-wins. `seen_count` is advisory and may lose increments under contention; schema and example converge regardless.

The advisory locks assume a local filesystem — don't point `data_dir` at NFS.

## Backends

Storage resolves through a backend abstraction, selected by `[storage].backend` or `GRAPH_STORAGE`:

| Backend          | Character               | Use when                                                |
| ---------------- | ----------------------- | ------------------------------------------------------- |
| `file` (default) | persistent, plain files | daily interactive use, CI that should learn across runs |
| `memory`         | ephemeral               | CI jobs and tests that should leave no state behind     |

The runtime depends only on a narrow storage trait (`Store`), so centralized backends (e.g. Postgres, with a **shared shape cache** every CI job inherits) can slot in without re-architecture.

## Operational notes

* Back up by copying `data_dir` — it's just files.
* Deleting a thread directory by hand is equivalent to `graph threads rm`.
* Deleting `shapes/` only costs learned planning hints; the cache rebuilds as tools run.


## Related topics

- [The shape cache](/tools/shape-cache.md)
- [Automation recipes](/cookbook/automation.md)
- [Threads](/using/threads.md)
- [Scripting contract](/reference/scripting-contract.md)
- [Installation](/getting-started/installation.md)
