Caching

Overview

When rendering documents with embedded computations becomes time-consuming, you may want to consider adding an execution cache, which will store the results of cell executions so they aren’t re-executed with every document render.

Quarto integrates with the Jupyter Cache and Knitr Cache to to cache time consuming code chunks. These two caching facilities distinct capabilities, and we’ll cover each in detail below.

Jupyter Cache

Jupyter Cache enables you to cache all of the cell outputs for a notebook. If any of the cells in the notebook change then all of the cells will be re-executed.

To use Jupyter Cache you’ll want to first install the jupyter-cache package:

Platform Command
Windows
py -m pip install jupyter-cache
Mac/Linux
python3 -m pip install jupyter-cache

To enable the cache for a document, add the cache option. For example:

---
title: "My Document"
format: html
execute: 
  cache: true
jupyter: python3
---

You can also specify caching at the project level. For example, within a project file:

project:
  type: website
  
format:
  html:
    theme: united
    
execute:
  cache: true

Note that changes within a document that aren’t within code cells (e.g. markdown narrative) do not invalidate the document cache. This makes caching a very convenient option when you are working exclusively on the prose part of a document.

Jupyter Cache include a jcache command line utility that you can use to analyze and manage the notebook cache. See the Jupyter Cache documentation for additional details.

Knitr Cache

The Knitr Cache operates at the level of individual cells rather than the entire document. While this can be very convenient, it also introduced some special requirements around managing the dependencies between cells.

You can enable the Knitr cache at the document or project level using standard YAML options:

---
title: "My Document"
format: html
execute: 
  cache: true
---

You can also enable caching on a per-cell basis (in this you would not set the document level option):

```{r}
#| cache: true

summary(cars)
```

There are a variety of other cell-level options that affect Knitr caching behavior. You can learn about them in the Knitr cell options reference. Another excellent resource is Yihui Xie’s article on cache invalidation.

Rendering

You can use `quarto render` command line options to control caching behavior without changing the document’s code. Use options to force the use of caching on all chunks, disable the use of caching on all chunks (even if it’s specified in options), or to force a refresh of the cache even if it has not been invalidated:

# use a cache (even if the document options don't enable it)
quarto render example.qmd --cache 

# don't use a cache (even if the documentation options enable it)
quarto render example.qmd --no-cache 

# use a cache and force a refresh (even if the cells haven't changed)
quarto render example.qmd --cache-refresh 

Alternatives

If you are using caching to mitigate long render-times, there are some alternatives you should consider alongside caching.

Disabling Execution

If you are working exclusively with prose / markdown, you may want to disable execution entirely. Do this by specifying the enabled: false execute option For example:

---
title: "My Document"
format: html
execute: 
  enabled: false
---

Note that if you are authoring using Jupyter .ipynb notebooks (as opposed to plain-text .qmd files) then this is already the default behavior: no execution occurs when you call quarto render (rather, execution occurs as you work within the notebook).

Freezing Execution

If you are working within a project and your main concern is the cumulative impact of rendering many documents at once, consider using the freeze option.

You can use the freeze option to denote that computational documents should never be re-rendered during a global project render, or alternatively only be re-rendered when their source file changes:

execute:
  freeze: true  # never re-render during project render
execute:
  freeze: auto  # re-render only when source changes

Note that freeze controls whether execution occurs during global project renders. If you do an incremental render of either a single document or a project sub-directory then code is always executed. For example:

# render single document (always executes code)
quarto render document.qmd

# render project subdirectory (always executes code)
quarto render articles

Learn more about using freeze with projects in the article on managing project execution.