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

# Graph health

> Checking the graph is sound, what a healthy report looks like, repairing one that is not, where the backups go, and the maintenance that runs without you asking.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base doctor
```

That is the whole first answer. It reads both tiers, reports on each, and exits nonzero when something is wrong, which makes it usable in a script as well as by eye.

## What healthy looks like

Each tier gets its own line: the graph file's path, its line count, its size, and confirmation that it ends with a newline. Then an overall verdict.

**Why the newline check matters.** The graph is a line-oriented text format. A file that does not end cleanly is a file something was interrupted while writing, and that is the shape almost every corruption takes.

**Next rung.** `base doctor --json` gives the same report machine-readable. Pair it with `base commands list`, `base project list` and `base ast list` when you want a full picture: healthy graph, star commands loaded, workspace registered, code maps present.

## Repairing

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base doctor --repair
```

**Why it works.** It quarantines the lines it cannot parse and atomically rewrites the good set, taking a snapshot before it does. Reads elsewhere in base use a lenient parser on purpose, so one bad line degrades your context rather than blanking it; `--repair` is what turns that degraded state back into a clean one.

**The gotcha.** Repair is not a substitute for knowing what went wrong. If a graph goes unhealthy repeatedly, something is writing to it that is not base.

## Rolling back

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base doctor --restore
base doctor --restore graph.nq.bak-repair-2026-08-25-101402
```

Bare `--restore` lists the snapshots available. Naming one restores it.

## Where the backups are

Every repair, restore, compact and purge snapshots the graph first, as a sibling file named `graph.nq.bak-<operation>-<timestamp>`. The newest ten are kept and older ones are rotated out.

**Why it works.** This is one backup path shared by every mutating operation, rather than each command inventing its own. Verified from source at `4866996`, the commit the shipped 0.13.2 binary was built from.

**The gotcha.** Ten is not many on a busy machine. If you want to keep a particular state, copy that snapshot somewhere else; it will rotate out.

## Maintenance that runs on its own

Tier graphs auto-compact at session start once they pass a size threshold, and a cooldown stops that from happening repeatedly.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base config get graph.auto_compact
base config get graph.compact_threshold_mb
base config get graph.compact_cooldown_hours
```

Defaults: on, 12MB, and 24 hours between compactions.

**The gotcha.** Compaction rewrites the graph. It snapshots first and it is atomic, but if you are debugging something that depends on the exact byte layout, turn `graph.auto_compact` off for the duration rather than being surprised by it.

## Manual maintenance

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base graph compact
base graph purge --stale
base graph purge --stale --days 60 --apply
```

`compact` deduplicates and canonicalizes. `purge --stale` removes notes that have gone unread past a threshold, and previews until you pass `--apply`.

**The gotcha.** The purge clock is recency of reading, not age. A note's `lastRead` is stamped every time `base recall` returns it, so this removes what you have not needed rather than what is old. See [Decisions and recall](/guides/decisions-and-recall#getting-it-back).

<Warning>
  Never hand-edit `graph.nq`. base's writes are atomic, they snapshot first, and they refuse to run against an already-unhealthy graph. A text editor does none of those things, and an interrupted manual edit is how graphs get corrupted in the first place.
</Warning>

## Next

<CardGroup cols={2}>
  <Card title="Debugging injection" icon="bug" href="/guides/debugging-injection">
    When the graph is fine and things still are not arriving.
  </Card>

  <Card title="Setup reference" icon="wrench" href="/reference/setup">
    Every `base doctor` flag.
  </Card>
</CardGroup>
