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

# State

> Save and restore optimized module state with ModuleState and PredictState

After an optimizer tunes a module, the improved instructions and demos live only in memory. `ModuleState` snapshots the mutable state of every `Predict` leaf in a module into a serializable value, so an optimized program can be saved to disk and reloaded in production without re-running optimization.

```rust theme={null}
// After optimization:
ModuleState::from_module(&module)?.save("optimized.json")?;

// In production:
let mut module = MyPipeline::new();
ModuleState::load("optimized.json")?.apply(&mut module)?;
```

## `ModuleState`

A `ModuleState` holds one `PredictState` per predictor, keyed by the leaf name the module declares via [`Predictors`](/docs/components/modules#predictor-discovery-predictors) (`predictors: BTreeMap<String, PredictState>`). The `BTreeMap` keeps JSON output stable across runs. The names are the same ones optimizer candidates and trace spans use — one naming contract across persistence, optimization, and capture.

| Method        | Signature                                                               | Behavior                                                                                                                                                                                                                                     |
| ------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from_module` | `fn from_module<M: Predictors + ?Sized>(module: &M) -> Result<Self>`    | Snapshots every declared `Predict` leaf (instruction override + demos).                                                                                                                                                                      |
| `apply`       | `fn apply<M: Predictors + ?Sized>(&self, module: &mut M) -> Result<()>` | Applies the state in place, stamping each restored leaf's trace name with its declared name. Every name in the state must resolve to a leaf in the module; unknown names are an error. Predictors not named in the state are left untouched. |
| `to_json`     | `fn to_json(&self) -> Result<String>`                                   | Serializes to pretty-printed JSON.                                                                                                                                                                                                           |
| `from_json`   | `fn from_json(json: &str) -> Result<Self>`                              | Deserializes JSON produced by `to_json`.                                                                                                                                                                                                     |
| `save`        | `fn save(&self, path: impl AsRef<Path>) -> Result<()>`                  | Writes `to_json` output to a file.                                                                                                                                                                                                           |
| `load`        | `fn load(path: impl AsRef<Path>) -> Result<Self>`                       | Reads a file written by `save`.                                                                                                                                                                                                              |

## `PredictState` and the JSON shape

`PredictState` is the serializable snapshot of a single predictor's mutable state.

| Field                  | Type             | Meaning                                                                                                                                                                                              |
| ---------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `demos`                | `Vec<JsonMap>`   | Demo rows as flat JSON objects: field name to value, with input and output fields merged into one object. Rows are split back into the predictor's typed `Demo<S>` via the signature schema on load. |
| `instruction_override` | `Option<String>` | The instruction override, if any. `null` means the signature default applies.                                                                                                                        |

A saved file therefore looks like:

```json theme={null}
{
  "predictors": {
    "answerer": {
      "demos": [
        { "question": "2+2?", "answer": "4" }
      ],
      "instruction_override": "Answer concisely."
    }
  }
}
```

## The install seam

State loading reaches predictors through the object-safe per-leaf view `PredictorInfo` (see [Modules](/docs/components/modules#predictor-discovery-predictors)). Its `load_state` method is the install seam: a **full** overwrite of the leaf's optimizable state (`instruction_override: None` clears the override, `demos` replaces the demo set), used by `ModuleState::apply` and by the optimizer's one-shot install of the winning candidate. Candidate *evaluation* never calls it — candidates are injected ambiently per call tree (see [Optimizers](/docs/components/optimizers)). Every `load_state` invalidates the leaf's cached instance overlay, so a candidate is data applied through the seam, never ad hoc field mutation.

## Compatibility behavior

There is no version field in the format. Compatibility is field level and structural:

| Situation                                             | Result                                                   |
| ----------------------------------------------------- | -------------------------------------------------------- |
| Missing `demos` or `instruction_override` in JSON     | Defaults apply (`serde(default)` on both fields).        |
| State names a leaf absent from the module             | `apply` returns an error listing the unknown predictors. |
| Demo rows do not fit the predictor's signature schema | `apply` returns `failed to load state for `name\`\`.     |
| Module has predictors the state does not name         | Left untouched, no error.                                |

## See also

* [Predict](/docs/components/predict)
* [Optimizers](/docs/components/optimizers)
* [Functional lane (fx)](/docs/components/fx)
* [Modules](/docs/components/modules)
* [Example: save and load state](https://github.com/krypticmouse/DSRs/blob/main/crates/dspy-rs/examples/13-save-load-state.rs)
