Caching
marimo-export and marimo reuse different work. The export repository reuses finished state and output data. marimo's computation cache reuses notebook cell results when a state still needs to run.
In the quickstart, the two kinds of reuse happen at different times:
| Request | marimo-export | marimo |
|---|---|---|
| First build | Run weekly and monthly | Restore compatible cells or execute them |
| Repeat the same build | Reuse the complete export | Does not start |
Change only the monthly input | Reuse weekly, run monthly | Restore compatible cells while the new state runs |
flowchart TD
request[Requested ExportSpec]
repository{Prepared work exists?}
reuse[Reuse prepared export or state]
execute[Run a missing state]
cache[Restore or execute marimo cells]
request --> repository
repository -->|yes| reuse
repository -->|no| execute
execute --> cachemarimo decides whether a cell can be restored
A marimo notebook is a reactive graph. Each cell defines names and refers to names from other cells. For automatic caching, marimo derives a cell key from the cell's compiled behavior, tracked references, and registered side effects.
On a usable hit, marimo restores compatible definitions and skips the cell body. On a miss, marimo executes the cell and persists the successful result.
When a state runs, these cells skip restoration and execute again. An output cell is the cell that marimo-export generates to select one output's value and convert it to the output's representation:
| Output | Cell that runs again | Reason |
|---|---|---|
cell source | The selected cell | Console records are uncached side effects |
anywidget.bundle | The output cell | The bundle reads the session's widget model |
Custom module:symbol | The output cell | The callable can read undeclared state |
File-based builds also track the distributions and local modules that the notebook imports, as defined in What the producer environment covers. Editing an imported helper or upgrading an imported package invalidates prepared results and automatic cell-cache entries. Adding an import that resolves to a distribution or local module outside the current scope changes that scope as well, so every automatic cell-cache entry runs again once. Explicit mo.cache and mo.persistent_cache calls retain their authored keys and reference dependencies. Other notebook-only edits still let marimo reuse unaffected cells. Restart a live notebook session after changing imported Python code so capture sees the new module values.
The article Content-Addressed Caching for Reactive Notebooks explains the graph-derived key model. marimo's caching reference defines the authoring APIs.
Tell marimo when external data changes
A file, network response, database row, clock read, or random draw can change while a cell key stays the same.
Use mo.watch.file or mo.watch.directory upstream when file contents affect a prepared result. Read the watcher value in the dependent cell. For other mutable sources, include an application-owned freshness value that changes when the result must run again.
An exact prepared-export hit returns before notebook execution, so a marimo watcher is consulted only after the export repository decides that execution is required. Change the producer inputs or output declarations when the application requires a new producer run.
Readers do not use either cache
| Store | Owns | Used by |
|---|---|---|
| marimo computation cache | Restorable notebook cell results | Producer execution |
| Export repository | Prepared states and exact prepared exports | Producer reuse |
| Notebook export | Canonical index.json and declared assets | Consumers |
A written notebook export remains readable after both producer-side stores are removed. Its readers select exported states and check output assets.
Related: Publishing covers how an application receives newer exports. Reuse defines exact identities, plan fields, and leases.