Job ci-dependency-cache-never-hits · revised 11 October 2026
Make one CI pipeline's dependency cache hit when dependencies are unchanged
On a re-run with unchanged dependency files, the named pipeline restores its cache and the install step finishes within the target you agreed. A changed lockfile still rebuilds the cache.
You might be seeing
- The cache step reports a miss, or no restore message, on a repeat run with no dependency change
- The install step is the longest part of every run, even for a one-line change
No passwords, keys, card details or admin invites needed to start.
What usually happened
A configured dependency cache never serves a later run. The key changes on every run, the cache is saved by a run whose branch scope later runs cannot read, the cached directory is not the one the package manager reads, or the restore happens after the install. Every run downloads and installs everything again while unused cache entries fill the storage allowance.
Who it’s for: A small engineering team whose pipeline reinstalls every dependency on every run even though a cache step is already configured, so each push waits several minutes for the install.
Usually starts when: The install step takes about as long on a repeat run as on the first run, and the cache step reports a miss, or restores something the install never uses.
The result: On a second run of the named pipeline with no dependency-file change, the job restores the cache saved by an earlier run, and its dependency step completes within the duration agreed before work starts. After a lockfile change the key changes and a fresh cache is saved.
Check whether this job fits
Answer from your own run history without sharing code or credentials. The result is a fit check, not permission to run your pipeline.
Checks you can run yourself
Compare two runs of the same job
Open a first run and a repeat run of the same job on the same branch and expand the cache step and the install step in each. Do not enable extra logging or re-run just for this check.
Look for: The key or hit status the cache step prints, the path it names, the directory the install command writes to, and the duration of each step. Remove secrets and customer details before sharing.
What you get
- A pull request with the cache change and a short note naming the cause
- Run links and redacted log excerpts for the cold run, the warm run and the run after a lockfile change
- A table of dependency-step durations from those runs, with the runner type
- Steps to revert the change
Included
- One pipeline in one repository, with one dependency cache and one package manager
- Read the cache step output of recent runs and compare the key, the cached path, the step order and the directory the install command reads
- Correct the key construction, cached path, step order or branch scope with the smallest change
- Measure the dependency step on a cold run, a warm run and a run after a lockfile change, on the same runner type
Not included
- Speed-ups that are not the dependency cache: test parallelism, runner size, container layer caching or build-output caching
- Changes to billing plans, cache storage allowances or repository settings
- Self-hosted runners or distributed cache storage that we cannot reach through an authorised route
- A guaranteed time saving or hit rate: network conditions and cache eviction vary between runs
- Adding a lockfile or changing which dependency versions the project resolves
How we know it’s done
Agreed with you before work starts. Each check produces evidence you keep.
On a repeat run with no dependency-file change, the named job's cache step reports an exact key hit and restores the cache saved by an earlier run.
Evidence: Run links for the cold and warm runs, with the cache step lines and the key shown for each.
The dependency step on the warm run completes at or below the duration agreed before work, measured on the same runner type as the cold run.
Evidence: A table of dependency-step durations for the cold, warm and changed-lockfile runs.
After a lockfile change, the next run reports a miss, installs from the registry and saves a new cache, and the run after that hits it.
Evidence: Three run links in order, with the cache step lines.
No secret value is printed or cached, and no workflow file or setting outside the cache change is touched.
Evidence: The complete changed-file list and the independently reviewed diff.
Sign-off. You inspect the warm run, the duration table and the changed-lockfile run, sign off in writing and merge the pull request. Payment follows sign-off.
If it fails. If the warm run does not hit the cache or does not meet the agreed duration, you do not pay for this fixed scope. If the cause is outside the cache, we explain what we found and stop; wider work needs a new written agreement.
When it fits, and when we stop
It fits when
- You can name the pipeline, job and cache step, and the recent runs are visible to you
- A lockfile is committed to the repository and the package manager installs from it
- The same pipeline can run on a branch with the usual trigger, without deploying
- Your maintainer can review and merge the change
We stop and tell you if
- The pipeline has so few runs that cache entries expire between them: we explain the eviction pattern and stop
- The install step is already short and the waiting is elsewhere: we send the timing breakdown and stop
- The cached directory holds credentials or private keys: we tell you before anything is cached and stop
- The pipeline cannot run on a branch without deploying or using production secrets
What could go wrong
Before merge, closing the pull request leaves your default branch unchanged. After merge, your maintainer can revert the commit. Cache entries created by our runs stay until they expire and are simply no longer used after the revert.
Scroll the table sideways to read it all.
| Risk | How we handle it |
|---|---|
| A key that is too broad restores stale dependencies and hides a lockfile change. | The key includes a hash of the lockfile, and acceptance includes a run after a lockfile change that must miss and then save. |
| A cache written by a low-trust trigger could be read by trusted runs. | We keep cache writes to push-type triggers and check the trigger list in review; pull requests from forks only read. |
| The warm run is faster only because the network was quick that day. | Acceptance compares the dependency step against the agreed target on the same runner type and requires the exact-hit message, not only a shorter time. |
An independent reviewer checks that the warm run really restored an earlier cache, that the key includes the lockfile, that nothing sensitive is cached and that no unrelated file changed. Your maintainer reviews and merges under your usual rules.
How we deliver
We arrange the work and independent review, then show you the result against the agreed checks. You keep authority over your systems.
- Agree the pipeline, the cache, the target duration for the dependency step and the branch-run permission in writing
- Read the cold and repeat run output, and compare the key, the cached path, the step order and the branch scope
- Record a baseline cold run and a repeat run before changing anything
- Make the smallest change that lets a later run restore the cache, keeping the lockfile in the key and restricting cache writes to push-type triggers
- Run the pipeline cold, warm and after a lockfile change, and record the durations and cache step lines
- Have an independent reviewer check the runs and the diff, then hand over the pull request and revert notes
This is a one-off job, not emergency cover or a subscription. We confirm eligibility, the total price, a start window and a delivery date before you accept. Work starts only after agreed inputs, secure access and necessary permissions are in place. Platform, runner and supplier charges are excluded unless the written quote includes them. No charge or booking is created by an enquiry.
Need to keep it working?
If run times drift back up as dependencies change, a monthly build-time budget can keep watching them.
Ongoing work is separately scoped and quoted: no monitoring, response-time guarantee or automatic subscription is included in this job.
Explore an ongoing engineering lane, or mention the responsibility you need in your enquiry.
What you can check
This is a new service. We have not delivered this job for a client yet.
Other ways to get this done
- Your maintainer can compare the cache key, the cached path and the cache scope rules with the platform's own caching guide before buying anything. docs.github.com
- On GitLab CI, the official caching guide explains cache keys built from file contents and why caches are an optimisation rather than a guarantee. docs.gitlab.com
Questions
Will this make my pipeline a set number of minutes faster?
No. We agree a target for the dependency step before work starts and measure it, but network speed and cache eviction vary, so no saving is promised.
What if the install is slow because the dependencies are simply large?
Then a working cache helps repeat runs only. We say so after the cold run, and the fixed job ends with the cache working, not with a smaller install.
Do you cache build outputs too?
No. This job covers one dependency cache. Caching build outputs or test results is a different change with different risks.
Send an enquiry
Send us
- The pipeline, job and cache step names, and the package manager in use
- The cache step output lines from one first run and one repeat run, with secrets removed
- The dependency step's duration in those two runs, as shown in the run summary
- Do not send credentials, source code or an access invitation in the first enquiry
Later, once you agree
- The pipeline file and the lockfile through an authorised company-controlled repository or code-export route, with a branch route for the pull request
- Read access to the named run logs using the least access needed
- Written approval for the branch runs and who reviews and merges; you keep all secret values
You own the repository, the CI account, the runners and the secrets. We read authorised pipeline files and redacted logs and work on a branch through a company-controlled identity, never a personal login. You approve branch runs and merge the pull request. We do not change repository settings, storage allowances or billing.
Email fallback: open your mail app
If website submission is unavailable, review and send the fallback email yourself. An email fallback is not a website receipt. Or write to hello@syntheticindustry.ai with “ci-dependency-cache-never-hits” as the subject.