> ## Documentation Index
> Fetch the complete documentation index at: https://wiki.latch.bio/llms.txt
> Use this file to discover all available pages before exploring further.

# Caching and Resuming

Running large workflows can be time-consuming and expensive, especially when tasks have already produced valid outputs in previous runs. Latch provides two ways to avoid recomputing work:

1. **Retry from failed task** – ideal for resuming failed runs without changing inputs.
2. **Task-level caching** – useful for skipping specific tasks across multiple runs, even when inputs change.

These features help save compute resources, shorten iteration cycles, and speed up debugging.

## 1. Default: "Retry from Failed Task"

By default, when a workflow fails, the Latch Console provides a Retry from failed task option. This resumes the workflow from the point of failure. Upstream tasks are skipped and their previous outputs are reused.

This is ideal when:

* Your inputs have not changed
* You fixed a bug in your code and want to re-run without repeating completed steps

## 2. Custom Caching for Select Tasks

If you want to launch multiple executions with different **workflow-level** inputs, but avoid re-running certain expensive tasks whose **own** inputs have not changed (e.g., rebuilding reference genomes), you can enable task-level caching.

This lets you persist outputs for those tasks across workflow runs, regardless of changes to unrelated workflow inputs upstream.

```python theme={null}
import time
from latch import small_task

@small_task(cache=True)
def do_sleep(foo: str) -> str:
    time.sleep(60)
    return foo
```

### Versioning Your Cache

Use `cache_version` to manually control when caches are invalidated:

```python theme={null}
@small_task(cache=True, cache_version="0.0.0")
def do_sleep_with_version(foo: str) -> str:
    time.sleep(60)
    return foo
```

* Change the version string to invalidate the cache, even if the code has not changed.
* Keep the same version to preserve cache even if the task body changes.

### Caching Rules

A task's cache is independent of the workflow it's in, meaning:

* Caches persist across workflow re-registrations if the task is unchanged.
* Caches are preserved if the task is reused in a different workflow.

Cache is invalidated when:

* Task code changes (non-comment)
* Function name or parameter types change
* `cache_version` changes

Cache is preserved when:

* Task code and signature remain identical (comments don't count)
* Task is reused in a new workflow without changes
