# Snakemake's, until and, target: How to Resume from a Specific Rule

Resuming a Snakemake workflow from a specific rule is a command-line skill, not a workflow rewrite. Snakemake is a bioinformatics workflow manager, a program that reads a description of your analysis steps, works out their dependencies, runs them in parallel where possible, and records what it did. That design gives you built-in tools for partial runs: `-until` stops after a rule, `-omit-from` skips a rule and everything before it, and positional targets request single files or rules directly.

By the end of this article you will be able to do all of the following:

1. Stop a workflow after any rule with `-until`.
2. Start a workflow at a later rule with `-omit-from`.
3. Run a single rule on demand, or rerun one rule and update everything downstream, with `-forcerun`.
4. Preview every partial run with `-dry-run` before spending compute.
5. Diagnose and fix `MissingInputException`, `IncompleteFilesException`, and surprise reruns.

What to have on hand:

- Snakemake 8.x, installed with `pip install snakemake` or from the bioconda channel. Snakemake 8 needs Python 3.11 or newer. Every command in this article also works on Snakemake 7 with minor differences in console wording.
- A terminal and the small example workflow provided below. The example creates its own placeholder files, so no biological data and no extra tools are required.
- Graphviz, the graph drawing tool, only if you want the DAG images in the verification step.

Two version facts prevent early confusion. First, Snakemake 8 requires the `-cores` flag on every execution. Omit it and the run stops immediately:

```
Error: you need to specify the maximum number of CPU cores with the --cores flag.
```

Snakemake 7 defaulted to a single core instead. Second, there is no `-target` flag in Snakemake, a detail that trips up many people looking for this exact feature. Targets are positional arguments, and the next section explains how they work.

## What Resuming Means in Snakemake

Snakemake does not execute a Snakefile from top to bottom. It parses the rules, takes the target files you requested, and builds a DAG (a directed acyclic graph, the map of which jobs depend on which). A rule is a named step that declares inputs, outputs, and a command. A job is one concrete execution of a rule, for example the align rule applied to sample A. A target is what you ask Snakemake to produce, given as a file path or a rule name on the command line. With no targets, Snakemake uses the first rule in the Snakefile as the default target, which is why most workflows begin with an aggregate rule named `all`. The order of the remaining rules in the file does not matter.

Resuming is built into this model in two ways.

First, every invocation is already a resume. For each output file a job would produce, Snakemake consults the metadata it wrote during earlier runs, stored under `.snakemake/metadata` as one record per file. The record captures the code, params, inputs, software environment, and modification time (mtime, the filesystem timestamp) behind the file. If all of those still match, the job is skipped as up to date. If every job in the DAG is current, Snakemake prints:

```
Nothing to be done (all requested files are present and up to date).
```

Second, you can bound the DAG from either end. The official Snakemake documentation describes the two flags this article centers on as follows:

- `-until RULE` runs everything the rule depends on, runs the rule, and stops there. Downstream rules never run in that invocation.
- `-omit-from RULE` removes the rule and everything upstream of it from the DAG, so execution starts at the rules that consume its outputs. Those outputs must already exist.

Positional targets narrow the run further, and `-forcerun` forces individual rules. The rest of the article walks through each pattern on a runnable example.

## A Small Example Workflow You Can Run

The walkthrough uses a four-rule RNA-seq-style skeleton. In a real pipeline the shell lines would call tools such as cutadapt for trimming, bwa for alignment, and featureCounts for counting. Here they call `touch`, which creates an empty file, so the example runs on any laptop. Save this as `Snakefile`:

```python
SAMPLES = ["A", "B"]

rule all:
    input:
        expand("results/counts/{sample}.tsv", sample=SAMPLES)

rule trim:
    input:
        "data/{sample}.fastq.gz"
    output:
        "results/trimmed/{sample}.fastq.gz"
    shell:
        "touch {output}"

rule align:
    input:
        "results/trimmed/{sample}.fastq.gz"
    output:
        "results/aligned/{sample}.bam"
    shell:
        "touch {output}"

rule counts:
    input:
        "results/aligned/{sample}.bam"
    output:
        "results/counts/{sample}.tsv"
    shell:
        "touch {output}"
```

The `{sample}` part is a wildcard, a placeholder that lets one rule handle every sample. Create the raw input files and check your version:

```bash
mkdir -p data
touch data/A.fastq.gz data/B.fastq.gz
snakemake --version
```

The last command prints a version string such as `8.24.0`. Any 8.x release works for every command here. The dependency chain is trim, then align, then counts, then `all`, with two jobs per analysis rule.

## How to Resume From a Rule in Snakemake, Step by Step

Run the following steps in order in a fresh directory. Each one shows the command and the output you should expect.

### Step 1: List the rules you can resume from

```bash
snakemake --list-rules
```

Expected output:

```
all
trim
align
counts
```

Rule names are what you will pass to `-until` and `-omit-from`, and they are case sensitive. The companion command prints the rules that can serve as targets:

```bash
snakemake --list-target-rules
```

Use it when you inherit a large workflow and need to know what can be requested on the command line.

### Step 2: Preview the partial run with a dry run

A dry run builds the DAG and lists every job it would run without executing anything. Always do this before a partial run:

```bash
snakemake --cores 8 --dry-run --until align
```

Expected output (one block per job, four in total):

```
Building DAG of jobs...
Job stats:
job      count
-----    -----
align        2
trim         2
total        4

[Tue Nov 11 09:30:10 2026]
rule trim:
    input: data/A.fastq.gz
    output: results/trimmed/A.fastq.gz
    jobid: 3
    reason: missing output file
    resources: tmpdir=/tmp

...

This was a dry-run (flag -n). The order of jobs does not reflect the order of execution.
```

Read the job stats table first. `-until align` kept the two trim jobs and the two align jobs, and dropped counts and `all`. The `reason` line under each job tells you why it is scheduled. A missing output file is the most common reason on a first run.

### Step 3: Run up to a rule with, until

```bash
snakemake --cores 8 --until align
```

Expected output:

```
Building DAG of jobs...
Job stats:
job      count
-----    -----
align        2
trim         2
total        4

[Tue Nov 11 09:30:12 2026]
rule trim:
    input: data/A.fastq.gz
    output: results/trimmed/A.fastq.gz
    jobid: 3
    reason: missing output file
    resources: tmpdir=/tmp

[Tue Nov 11 09:30:13 2026]
Finished job 3.
1 of 4 steps (25%) done

...

[Tue Nov 11 09:30:15 2026]
Finished job 1.
4 of 4 steps (100%) done
Complete log: .snakemake/log/2026-11-11T093012.481620.snakemake.log
```

`-until` ran the whole upstream chain and then stopped. counts and `all` never ran. Run the same command again:

```bash
snakemake --cores 8 --until align
```

```
Building DAG of jobs...
Nothing to be done (all requested files are present and up to date).
Complete log: .snakemake/log/2026-11-11T093355.221040.snakemake.log
```

The selection is not saved anywhere. A plain `snakemake, cores 8` at this point would continue downstream and produce the counts files and the `all` target. `-until` only bounds the invocation you pass it to.

### Step 4: Start from a rule with, omit-from

`-omit-from` is the other end of the run. It removes the named rule and everything upstream of it from the DAG, so execution starts with the rules that consume its outputs:

```bash
snakemake --cores 8 --omit-from trim
```

Expected output, given that Step 3 already produced the trimmed and aligned files:

```
Building DAG of jobs...
Job stats:
job      count
-----    -----
all          1
counts       2
total        3

[Tue Nov 11 09:41:02 2026]
rule counts:
    input: results/aligned/A.bam
    output: results/counts/A.tsv
    jobid: 0
    reason: missing output file
    resources: tmpdir=/tmp

...

3 of 3 steps (100%) done
Complete log: .snakemake/log/2026-11-11T094102.901210.snakemake.log
```

Two things happened at once. trim is gone because `-omit-from` removed it and its upstream. align is absent from the job list because its outputs were already current from Step 3, which is the automatic resume behavior doing its job.

On a fresh directory, where the trimmed files do not exist, the same command fails before anything runs:

```
Building DAG of jobs...
MissingInputException in rule align in file /home/user/rnaseq/Snakefile, line 15:
Missing input files for rule align:
input: results/trimmed/A.fastq.gz
input: results/trimmed/B.fastq.gz
```

The fix is to confirm that the omitted rules' outputs really exist before you omit them. List the directory, or produce them first with a bounded `-until` run. The exact wording of this error varies a little between Snakemake versions, but the exception name and the rule name are stable.

### Step 5: Run a slice between two rules

Combine both flags to run a middle section. First create work for it by deleting the downstream files:

```bash
rm results/aligned/*.bam results/counts/*.tsv
snakemake --cores 8 --omit-from trim --until align
```

Expected output:

```
Building DAG of jobs...
Job stats:
job      count
-----    -----
align        2
total        2
```

Only the two align jobs run. This pattern is handy for debugging one stage: keep the inputs from the previous stage fixed, rerun the stage in isolation, and inspect its outputs.

### Step 6: Rerun one rule and everything downstream

After you edit a rule, for example to fix the align command, you usually want that rule and its downstream rules rerun, and nothing upstream touched:

```bash
snakemake --cores 8 --forcerun align
```

Expected output:

```
Building DAG of jobs...
Job stats:
job      count
-----    -----
all          1
align        2
counts       2
total        5

[Tue Nov 11 09:52:20 2026]
rule counts:
    input: results/aligned/A.bam
    output: results/counts/A.tsv
    jobid: 0
    reason: missing output file
    resources: tmpdir=/tmp

...

5 of 5 steps (100%) done
Complete log: .snakemake/log/2026-11-11T095220.334501.snakemake.log
```

trim does not appear because it is up to date and was not forced. align runs again because `-forcerun` named it, and counts and `all` follow because their inputs changed or were missing. `-forcerun` accepts rule names or file paths.

### Step 7: Verify the result

Three checks cover most cases. First, a dry run of the full workflow should report no work:

```bash
snakemake --cores 8 --dry-run
```

```
Building DAG of jobs...
Nothing to be done (all requested files are present and up to date).
```

Second, confirm the files themselves exist:

```bash
ls results/trimmed results/aligned results/counts
```

```
results/aligned:
A.bam  B.bam

results/counts:
A.tsv  B.tsv

results/trimmed:
A.fastq.gz  B.fastq.gz
```

Third, ask Snakemake for the status of every output file:

```bash
snakemake --summary
```

The table lists each output file with the rule that produced it, a timestamp, and a status, and the column layout varies slightly between versions:

```
output_file                          date                 rule      version    log-file    status
results/trimmed/A.fastq.gz           2026-11-11 09:30:14  trim      8.24.0     ...         ok
results/trimmed/B.fastq.gz           2026-11-11 09:30:14  trim      8.24.0     ...         ok
results/aligned/A.bam                2026-11-11 09:52:21  align     8.24.0     ...         ok
results/aligned/B.bam                2026-11-11 09:52:21  align     8.24.0     ...         ok
results/counts/A.tsv                 2026-11-11 09:52:22  counts    8.24.0     ...         ok
results/counts/B.tsv                 2026-11-11 09:52:22  counts    8.24.0     ...         ok
```

A status of ok means the file is current. After you edit a rule, the files it produces flip to needs update, and a file whose input is gone shows missing input file. For a visual check, export the DAG that a partial run would use:

```bash
snakemake --dag --until align | dot -Tsvg > dag_until_align.svg
```

`-dag` implies a dry run and prints the graph in Graphviz DOT format, so Graphviz must be installed. The exported picture should show trim and align for both samples and nothing else.

## Key Options for Partial Runs

![Decision path asking if you want to stop after a rule, start later, or rerun one rule, ending on the matching Snakemake flag.](/article-images/illustrations/snakemake-resume-from-rule-resume-choice.webp)

The table collects the options that matter when you resume from a rule.

| Option | What it does | Use it when |
|, - |, - |, - |
| `-until RULE` | Runs everything RULE depends on, then RULE, then stops | You want the workflow up to a known point |
| `-omit-from RULE` | Drops RULE and its upstream from the DAG | You want to start at a later rule whose inputs already exist |
| positional targets | File paths or rule names placed after the options | You want one sample, one file, or one aggregate output |
| `-dry-run` (`-n`) | Builds the DAG and lists jobs without executing | Before any partial run |
| `-force` | Reruns the jobs for the requested targets even when up to date | Your targets are current but wrong |
| `-forceall` | Reruns every job in the DAG | A global change, such as a new reference, touches everything |
| `-forcerun RULE` | Forces the named rule, then lets downstream jobs update | You fixed one rule's command |
| `-rerun-triggers` | Selects which changes mark a file out of date: code, input, mtime, params, software-env | Cosmetic edits keep triggering reruns |
| `-touch` | Marks outputs current by updating timestamps, without running commands | Files were produced or restored outside Snakemake |
| `-rerun-incomplete` | Reruns jobs that a previous crash left unfinished | A run was killed mid-job |
| `-summary` | Prints one row per output file with its status | You want to know what would rerun |
| `-reason` | Prints why each job runs | A dry run schedules more than you expected |
| `-cores N` | Sets the number of parallel jobs, required in Snakemake 8 | Always |

**Rerun triggers deserve a closer look.** Since Snakemake 7.8, the default up-to-date check covers five triggers: code (the rule's shell or Python code), input (the input files and their timestamps), mtime (output older than input), params (the values in the params section), and software-env (the conda environment or container image). The official Snakemake documentation lists exactly these. `-rerun-triggers mtime` narrows the check to timestamps alone, which is the main lever you have when you want a resume to ignore small edits.

**`-touch` adopts outside files.** If a colleague handed you finished intermediate files, `snakemake, cores 1, touch` walks the DAG and updates the timestamp of every output instead of running commands. For files copied from another location, clear the stale record first with `snakemake, cleanup-metadata results/trimmed/A.fastq.gz`, then touch.

**`-rerun-incomplete` repairs crashed runs.** A killed run leaves half-written outputs, and Snakemake refuses them on the next pass until you pass this flag.

## Practical Tips for Resuming From a Rule

1. **Dry-run first, every time.** `-dry-run` costs seconds and shows the exact job set. Read the job stats table and confirm the boundary rules are where you intended.
2. **Read the reason lines.** Snakemake prints why each job runs, for example `reason: missing output file` or `reason: code has changed since last execution`. If a reason does not match your intention, stop and adjust the flags before compute is spent.
3. **Slice with both flags.** `-omit-from` sets the near boundary and `-until` sets the far one. Together they isolate any stage of a linear workflow.
4. **Adopt files made outside Snakemake.** `-touch` registers them as current, and `-cleanup-metadata` clears records that point to old locations.
5. **Scope the rerun triggers after cosmetic edits.** `-rerun-triggers mtime` restricts the up-to-date check to timestamps. Real code changes then stop triggering reruns, so use it deliberately and do a full run before final results.
6. **Preview what an edit invalidates.** `snakemake, list-code-changes`, `-list-params-changes`, and `-list-input-changes` print the files a given trigger would affect, without running anything.
7. **Keep long partial runs moving.** `-keep-going` (`-k`) continues with independent jobs after a failure, and `-printshellcmds` (`-p`) prints each command, which makes logs readable.
8. **Use the logs.** Each run writes a timestamped file under `.snakemake/log`, and the Complete log line at the end of a run names it. Diffing two logs shows exactly what a flag change did.
9. **The same flags work on a cluster.** Snakemake 8 dispatches through executor plugins, for example `-executor slurm` after installing `snakemake-executor-plugin-slurm`. SLURM is the scheduler on most university clusters. `-until` and `-omit-from` behave identically there.
10. **Use `-until` as a smoke test in continuous integration.** Running a workflow up to a cheap rule on a tiny test dataset catches broken rules in seconds.

Once the partial-run commands your project needs are settled, write them into the workflow README or a small helper script so the whole team reuses the same entry points. The official Snakemake command-line reference is the authoritative list of every flag used here, including the complete set of rerun triggers.

## Common Mistakes and Limitations

1. **Typing `-target`.** Snakemake has no such option. The parser answers with a usage block followed by:
   ```
   snakemake: error: unrecognized arguments: --target foo
   ```
   Pass targets positionally instead, for example `snakemake results/aligned/A.bam` or `snakemake all`. The similarly named `-list-target-rules` option lists rules, it does not set a target.
2. **Expecting `-until` to run a single rule.** `-until` runs the rule's entire upstream chain first. If the upstream outputs are current they are skipped in seconds, but on a fresh directory the run builds them, because the rule cannot execute without its inputs. To run one rule against existing inputs, `-until` is enough. To rerun it regardless of status, use `-forcerun`.
3. **Omitting a rule whose outputs do not exist.** `-omit-from` does not create the files the skipped rule would have made. Downstream rules then fail at DAG build time with the `MissingInputException` shown in Step 4. Check that the intermediate files exist, or produce them with a bounded `-until` run first.
4. **Treating a partial run as saved state.** `-until` and `-omit-from` apply to one invocation. Nothing is stored, and the next plain `snakemake` run continues downstream. Do not look for a config entry or lock file that preserves the boundary, because none exists.
5. **Surprise reruns after harmless edits.** Reformatting a shell command, reordering params, or updating a conda environment file counts as a change under the default rerun triggers. The next run regenerates the affected files and everything downstream. Diagnose with `snakemake, summary` before running, and scope the check with `-rerun-triggers` when the edit was truly cosmetic.
6. **Resuming after a crash without `-rerun-incomplete`.** A killed run leaves half-written outputs recorded under `.snakemake/incomplete`. The next run refuses them:
   ```
   IncompleteFilesException:
   The files below seem to be incomplete. If you are sure you want to run them, use the --rerun-incomplete flag.
   	results/aligned/A.bam
   ```
   Rerun with `-rerun-incomplete` and Snakemake regenerates exactly those files.
7. **Requesting a wildcard rule by name.** A rule with wildcards in its outputs, such as align with `{sample}`, is best requested through concrete file paths like `results/aligned/A.bam`. Rules without wildcards, including aggregate rules such as `all`, can be typed directly. If a name-only request does not resolve the way you expect, switch to the file path.
8. **Partial runs around checkpoints.** A checkpoint is a rule declared with the `checkpoint` keyword whose outputs are discovered while the workflow runs, which lets the DAG grow dynamically. `-until` and `-omit-from` are evaluated against the DAG as it exists when the run starts. Around checkpoints, a partial run can therefore cover a different set of jobs than the same flags suggest from the finished workflow. Dry-run carefully and prefer full runs for checkpoint-heavy sections.
9. **Trusting exact error wording.** Messages differ between Snakemake 7 and 8 and between minor releases. Read the exception class, the rule name, and the file list, which are stable, rather than the sentence around them.
10. **Limitations.** A partial run is only as trustworthy as the DAG you think you are running. Validate any new partial-run command against a full run on a small test dataset before using it on real data. For pipelines that feed clinical or diagnostic decisions, a qualified professional must review the results before release.

## Nextflow vs Snakemake for Partial Reruns

![Comparison table of Snakemake and Nextflow across up-to-date check, resume flag, mid-pipeline entry and cluster dispatch.](/article-images/illustrations/snakemake-resume-from-rule-snakemake-nextflow.webp)

Nextflow vs Snakemake is a common comparison for this exact task, because both are established bioinformatics workflow managers and both avoid repeating finished work.

Snakemake rechecks every output file against its stored metadata on every invocation. Up-to-dateness is a property of files, so any process that leaves the expected files in place, run once by hand or by another tool, is enough to make later runs skip upstream. `-until` and `-omit-from` add explicit, named-rule control over where a run starts and stops.

Nextflow takes a different approach. Each process execution is cached in the pipeline's work directory, keyed by a hash of its inputs, code, and container. The `-resume` flag reuses those cached tasks whenever their hash is unchanged, which makes reruns cheap and mostly automatic. There is no direct equivalent of `-until`. Partial execution in Nextflow is usually achieved through `-resume` caching, or by structuring the pipeline so the section you want is its own sub-workflow.

In practice, Snakemake makes mid-pipeline entry points a command-line concern, while Nextflow pushes them into pipeline design. Teams invested in the nf-core collection, which is Nextflow-based, usually stay there. Labs that want Python-native syntax and file-level control often choose Snakemake. Both run well on HPC schedulers, Snakemake 8 through executor plugins and Nextflow through built-in support for common schedulers such as SLURM.

## Frequently Asked Questions

### Does Snakemake have a, target flag?

No. Snakemake takes targets as positional arguments, either file paths or rule names, and its parser rejects `-target` as an unrecognized argument. Request a file with `snakemake results/aligned/A.bam` or an aggregate rule with `snakemake all`.

### How do I start a Snakemake pipeline from a specific rule?

Use `-omit-from` with the last rule you want to skip, for example `snakemake, cores 8, omit-from trim`. Snakemake drops that rule and everything upstream of it and runs the rest, which only works when the skipped rules' outputs already exist.

### What is the difference between, until and, omit-from?

`-until` sets the far end of a run and stops after the named rule completes. `-omit-from` sets the near end and removes the named rule and its upstream from the DAG. Used together, they run a slice between two rules.

### Why does Snakemake rerun steps that already finished?

A rerun trigger changed since the last execution: the rule code, params, inputs, software environment, or file timestamps. Run `snakemake, summary` or `snakemake, list-code-changes` to see which files are affected before you rerun.

### Can I run exactly one rule and nothing else?

Yes. `snakemake, cores 8, until myrule` runs only that rule when its inputs are already up to date, and `snakemake, cores 8, forcerun myrule` runs it even when it is current.

### How do I force a rerun of one rule after changing its code?

Run `snakemake, cores 8, forcerun myrule`. Snakemake reruns that rule and then updates every downstream job that consumes its outputs. Use `-force` or `-forceall` for broader reruns.

### What does "Nothing to be done (all requested files are present and up to date)" mean?

Every requested file exists and still matches the metadata from the run that produced it, so there is no work left for that invocation. If you expected work, check your targets or force a rerun.

### How does Snakemake's resume behavior compare with Nextflow -resume?

Snakemake rechecks each output file against stored metadata on every run and skips current files. Nextflow caches finished tasks in its work directory and reuses them when you pass `-resume`. Snakemake additionally offers `-until` and `-omit-from`, which have no direct Nextflow equivalent.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Does Snakemake have a, target flag?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. Snakemake takes targets as positional arguments, either file paths or rule names, and its parser rejects, target as an unrecognized argument. Request a file with snakemake results/aligned/A.bam or an aggregate rule with snakemake all."
      }
    },
    {
      "@type": "Question",
      "name": "How do I start a Snakemake pipeline from a specific rule?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Use, omit-from with the last rule you want to skip, for example snakemake, cores 8, omit-from trim. Snakemake drops that rule and everything upstream of it and runs the rest, which only works when the skipped rules outputs already exist."
      }
    },
    {
      "@type": "Question",
      "name": "What is the difference between, until and, omit-from?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "-until sets the far end of a run and stops after the named rule completes., omit-from sets the near end and removes the named rule and its upstream from the DAG. Used together, they run a slice between two rules."
      }
    },
    {
      "@type": "Question",
      "name": "Why does Snakemake rerun steps that already finished?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A rerun trigger changed since the last execution: the rule code, params, inputs, software environment, or file timestamps. Run snakemake, summary or snakemake, list-code-changes to see which files are affected before you rerun."
      }
    },
    {
      "@type": "Question",
      "name": "Can I run exactly one rule and nothing else?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. snakemake, cores 8, until myrule runs only that rule when its inputs are already up to date, and snakemake, cores 8, forcerun myrule runs it even when it is current."
      }
    },
    {
      "@type": "Question",
      "name": "How do I force a rerun of one rule after changing its code?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Run snakemake, cores 8, forcerun myrule. Snakemake reruns that rule and then updates every downstream job that consumes its outputs. Use, force or, forceall for broader reruns."
      }
    },
    {
      "@type": "Question",
      "name": "What does Nothing to be done (all requested files are present and up to date) mean?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Every requested file exists and still matches the metadata from the run that produced it, so there is no work left for that invocation. If you expected work, check your targets or force a rerun."
      }
    },
    {
      "@type": "Question",
      "name": "How does Snakemake's resume behavior compare with Nextflow -resume?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Snakemake rechecks each output file against stored metadata on every run and skips current files. Nextflow caches finished tasks in its work directory and reuses them when you pass -resume. Snakemake additionally offers, until and, omit-from, which have no direct Nextflow equivalent."
      }
    }
  ]
}
</script>