Skip to main content

Cache

Dagger cache follows the graph.

Same inputs, same work, same result: Dagger can reuse it.

Different inputs: Dagger reruns the affected work.

This is why module API design affects speed.

Function Cache Hits

A function cache hit skips the function entirely, so none of its internal steps run. A cache miss runs the function, but individual container/file steps inside it may still be cache hits if their inputs are unchanged.

If you need a specific step to always re-run, add a cache-busting input to that step. If you need non-secret metadata to be visible to a withExec step without invalidating cache when only that metadata changes, use withVolatileVariable on the Container. Cached withExec results may be reused even when the volatile value changes, and reruns caused by other inputs will see the latest volatile value. See Container volatile variables.

Inputs Matter

Precise inputs make precise cache keys.

Use narrow inputs:

  • the package directory, not the whole repo
  • the lock file, not every generated file
  • the file being processed, not every file nearby
  • the secret needed for one step, not hidden host credentials

Broad inputs make broad invalidation. If a lint function accepts the whole repo, a README change can rerun work that only needed source files.

Outputs Matter

Composable outputs help cache too.

Return a Container, Directory, File, or object when the caller may keep building. Let the caller decide when to materialize.

Materialize only when the function is meant to produce a final result.

Cache Volumes

Cache volumes are for tool caches:

  • package downloads
  • compiler caches
  • dependency stores
  • other mutable acceleration data

They are not source of truth. A module must still be correct with an empty cache.

Cloud Cache

Local and CI caches are often separate. Dagger Cloud can share cache across environments.

Do not depend on a warm cache. Design for correctness first, speed second.

Design Check

Ask:

  • Does each function accept the smallest meaningful Directory or File?
  • Are tool versions pinned?
  • Are generated files excluded unless needed?
  • Does the function return a composable value?
  • Can the caller understand why work reran?

Next: Execution.