---
name: cachely-improve-cache-hit-rate
description: Diagnose remote cache misses and raise the cache hit rate for Nx, Lerna, Turborepo, Gradle, or Bazel builds. Use when cache hits are rarer than expected, CI keeps re-executing unchanged tasks, or two machines compute different hashes for the same task.
---

# Improving your cache hit rate

A miss means the computed hash differs between runs. Find what changed in
the hash inputs, then remove the noise. Work top-down: the highest-volume
misses first (Cachely's dashboard insights at https://app.cachely.dev show
hits, misses, and puts per project/target).

## 1. Confirm the cache is actually consulted

- A challenge page, proxy, or missing token makes every request fail
  quietly on some tools. Verify a manual round trip succeeds and CI has the
  token secret set (see the `cachely-ci-setup` skill).
- Over-quota workspaces degrade to misses by design; check plan usage.

## 2. Compare the two runs' hash inputs

- **Nx**: run with `NX_VERBOSE_LOGGING=true`, or compare
  `nx hash <task>` output between machines.
- **Turborepo**: `turbo run build --dry=json` prints each task's hash and
  the inputs that fed it; diff two runs.
- **Gradle**: `--scan` or `-Dorg.gradle.caching.debug=true` logs the build
  cache key inputs per task.
- **Bazel**: `--execution_log_json_file` captures per-action inputs; diff.

## 3. Remove the usual noise sources

- **Over-broad inputs**: a task keyed on the whole repo misses on every
  commit. Narrow `inputs` to the files the task reads.
- **Environment variables**: CI-injected vars (`CI`, ephemeral URLs, build
  numbers) listed in `env`/inputs change every run. Hash only vars that
  change the output.
- **Lockfile and toolchain drift**: different Node/JDK versions or an
  un-pinned dependency resolve differently per machine. Pin via `.nvmrc`,
  toolchains, lockfiles - and make CI honor them.
- **Generated files committed or produced pre-task**: timestamps and
  absolute paths inside them poison the hash. Generate deterministically or
  exclude from inputs.
- **Line endings and file modes**: enforce `.gitattributes` so Windows and
  Linux hash identical bytes.
- **Undeclared outputs**: the task "hits" but restores nothing useful, so a
  downstream task misses. Declare every output path.

## 4. Structure for cacheability

- Split coarse tasks: one repo-wide `test` misses whenever anything
  changes; per-project tasks hit for everything untouched.
- Keep affected detection on (`nx affected`, `turbo --affected`) so skipped
  tasks do not even consult the cache.

## Realistic targets

Warm-branch CI runs on an active workspace commonly reach 70%+ task reuse.
If a specific target never hits, treat it as non-hermetic and fix it with
the `cachely-enable-task-caching` skill.
