Code Execution

Overview

Rendering a list of input files has the potential to be quite time consuming depending on the computations required. There are a number of techniques you can use to minimize the time required to rebuild a site that has expensive computations.

Incremental Render

When working on a project you are typically iterating on a single document at a time. You can render a single file (or single directory or list of files) incrementally by specifying it on the command-line:

quarto render introduction.qmd
quarto render subdir/

Even though you are rendering only part of the project, any associated project-handling code is still executed. So for exmaple in a book project the entire book is still produced (using previously rendered versions of the other chapters).

Freeze

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

Using Freeze

Freeze is generally used when you have either a large number of collaborators or many computational documents created over a longer period of time. In both cases it can be challenging to fully re-execute every document when you render the site. This could be because some documents have esoteric or environment-specific requirements (e.g. require access/authentication to a data source) or due to general fragility of dependencies over time. Using freeze ensures that you can always reproducibly render your site.

The computational results of documents executed with freeze are stored in the _freeze directory, and re-used when needed to fulfill document renders. You should check the contents of _freeze into version control so that others rendering the project don’t need to reproduce your computational environment to render it in their environment.

Note that you’ll still want to take care to fully re-render your project when things outside of source code change (e.g. input data). You can remove previously frozen output by deleting the _freeze folder at the root of yourproject.

Virtual Environments

You can also combine freeze with the use of virtual environments to divide your project into sub-directories that each have their own set of dependencies. This allows multiple collaborators to use a set of localized dependencies for the documents they are responsible for, but at the same time still be able to render the entire project without requiring all of its dependencies.

To learn how to create and use a virtual environment, see the full documentation on Virtual Environments

Here’s an example workflow of using virtual environments with freeze:

  1. Include freeze: true in the project execution options:

    execute:
      freeze: true
  2. Create a sub-directory of documents (e.g. research), and initialize and use a virtual environment within it:

    research/
      document1.qmd
      document2.qmd
      env/
      requirements.txt
  3. When working wihtin this sub-directory, activate the virtual environment before rendering its documents. For example:

    cd research
    source venv/bin/activate
    quarto render               # render all files in subdir
    quarto render document.qmd  # render a single-file

This sub-directory render won’t use the cached freeze results but instead will re-run all of the computations using the directory-specific virtual environment. You can of course also include sub-directories within this directory and their documents will also be rendered using the parent virtual environment.

Cache

You can use the cache option to cache the results of computations (using the knitr cache for R documents, and Jupyter Cache for Jupyter documents):

execute:
  cache: true

Note that cache invalidation is triggered by changes in chunk source code (or other cache attributes you’ve defined). You may however need to manually refresh the cache if you know that some other input (or even time) has changed sufficiently to warrant an update. To do this, render either individual files or an entire project using the --cache-refresh option:

quarto render mydoc.qmd --cache-refresh # single doc
quarto render --cache-refresh           # entire project

Notebooks

Note that when rendering an .ipynb Quarto will not execute the cells within the notebook by default (the presumption being that you already executed them while editing the notebook). If you want to execute the cells you can pass the --execute flag to render:

quarto render jupyter-document.ipynb --execute

You can also specify this behavior within the notebook’s YAML front matter:

---
title: "My Document"
execute: true
jupyter: python3
---

Working Dir

By default, the working directory for rendering files within a project is the directory of the file itself. If you prefer to use the main project directory instead, you can add the execute-dir: project option to your config:

project:
  execute-dir: project

Note that from within your code you can always determine the location of the currently executing Quarto project using the QUARTO_PROJECT_DIR environment variable.