Use Freeze to Cache Expensive Notebooks
If your documentation includes computationally expensive notebooks you can use Quarto’s freeze feature to persist execution outputs and skip re-execution on subsequent builds.
The Problem
Without freeze, every great-docs build re-executes all .qmd notebooks from scratch. For projects with heavy computations this might mean:
- 30–45 minute CI runs on every PR
- fragile builds (transient sampling failures break unrelated PRs)
- painful local iteration (every build is a cold start)
The Solution
Quarto’s freeze stores executed outputs in a _freeze/ directory. Once frozen, notebooks are only re-executed when their source changes (with freeze: auto) or never during project renders (with freeze: true).
Great Docs integrates this natively. Just set freeze in your config:
great-docs.yml
# Cache computational outputs across builds
freeze: autoHow It Works
freeze: autoaddsexecute: freeze: autoto the generated_quarto.ymlre-execution occurs only when the source has changed.Great Docs automatically injects a pre-render hook that restores
_freeze/into the build directory before rendering. No extra scripts or configuration needed.Because Great Docs recreates the build directory on each build, this automatic restoration ensures the freeze cache is always available when Quarto looks for it.
Step-by-Step Setup
1. Enable freeze in great-docs.yml
great-docs.yml
freeze: autoThis setting means that no pre-render scripts need be created or managed.
2. Run the initial freeze
Execute your expensive page(s) and capture their outputs:
Terminal
great-docs freeze user_guide/benchmarks.qmd3. Commit _freeze/ to version control
The great-docs freeze command automatically persists the cache to your project root. Just commit it:
Terminal
git add _freeze/
git commit -m "Persist freeze cache for docs builds"Now subsequent builds (locally and in CI) will restore the cache and skip re-execution.
Updating the Freeze Cache
When you change a frozen page’s source code or input data, use the great-docs freeze command to re-execute it and update the cache:
Terminal
great-docs freeze user_guide/benchmarks.qmdThis command:
- Renders the specified page inside the build directory (always executing code)
- Copies the updated
_freeze/entries back to your project root - Tells you exactly what to commit
You can freeze multiple pages at once:
Terminal
great-docs freeze user_guide/benchmarks.qmd user_guide/mcmc-demo.qmdOr specify a custom persistence directory:
Terminal
great-docs freeze user_guide/benchmarks.qmd --freeze-dir docs/_freezeThe command prints a ready-to-use git add + git commit hint when it finishes.
CI Workflow
In your GitHub Actions workflow, the freeze cache is automatically available because it’s checked into the repo:
.github/workflows/docs.yml
- name: Build docs
run: great-docs buildNo extra CI cache steps are needed as _freeze/ is in the repo and Great Docs handles the rest.
Advanced: Additional Pre-render Scripts
If you need custom scripts to run before rendering (e.g., data generation), add them via pre_render. Great Docs automatically runs the freeze restore before your scripts so you don’t need to include it yourself:
great-docs.yml
freeze: auto
pre_render:
- scripts/generate-data.pyScripts run in order after the freeze restore, and each must exist at the specified path relative to your project root.
When to Re-execute
The freeze cache should be refreshed when:
- Input data changes (not just source code)
- Package API changes affect output
- You want to update rendered figures or tables
To re-execute specific pages:
Terminal
great-docs freeze user_guide/benchmarks.qmdTo force a full re-execution of all frozen pages, use --clean:
Terminal
great-docs freeze --clean user_guide/benchmarks.qmd user_guide/sampling.qmdBuild Log
When freeze is configured, the build log reports it:
Step 1 Prepare build directory ················· Ready
Freeze mode: auto
This confirms that the freeze configuration is active and the cache restore will happen automatically.
Page-Level Freeze
You don’t have to freeze your entire site. If only one or two pages are expensive (e.g., a benchmarks page), use page-level freeze by adding freeze: to that page’s YAML frontmatter:
user_guide/benchmarks.qmd
---
title: "Benchmarks"
freeze: auto
---
# Benchmarks
This page runs extensive MCMC sampling that takes ~20 minutes...Great Docs automatically normalizes this shorthand into the nested form Quarto requires (execute: freeze: auto) during the build. You can also use the full Quarto syntax if you prefer:
user_guide/benchmarks.qmd
---
title: "Benchmarks"
execute:
freeze: auto
---Both forms are equivalent.
With page-level freeze only (no project-wide freeze: key), Great Docs still automatically restores _freeze/ when any page has freeze frontmatter. However, to ensure the restore runs reliably, set freeze: auto project-wide (it has no effect on pages without the freeze frontmatter key).
This way:
- Most pages render fresh on every build (picking up code changes immediately)
- Frozen pages (like
benchmarks.qmd) skip execution unless their source changes - The cache restore happens automatically (no extra scripts needed)
Which pages are cached?
The _freeze/ directory stores outputs per-page. After a build, you’ll see entries like:
_freeze/
└── user_guide/
└── benchmarks/
└── execute-results/
└── html.json
Only pages with freeze: (or execute: freeze:) in their frontmatter produce entries here. Commit only those entries to version control.
Mixing project-level and page-level
You can also combine both approaches:
- Set
freeze: autoproject-wide (all pages frozen by default) - Override specific pages with
freeze: falsein their frontmatter to force re-execution
a-page-that-must-always-execute.qmd
---
title: "Live Status"
freeze: false
---