---
title: "Reuse downloaded tools across runs"
description: "Cache versioned tools and browser downloads so jobs can restore them while retaining installation and repair checks."
url: https://starsling.dev/ci-playbooks/techniques/cache-tool-downloads
canonicalUrl: https://starsling.dev/ci-playbooks/techniques/cache-tool-downloads
---

# Reuse downloaded tools across runs

Cache versioned tools and browser downloads so jobs can restore them while retaining installation and repair checks.

## How to choose an approach

Compare the examples by repository setup, prerequisites, and risks before adopting one. Each company implemented this in its own environment; measure each change against your own baseline.

- **[Anthropic](https://starsling.dev/ci-playbooks/anthropic#cache-lint-tools)**: Use it when Installing or compiling a lint tool takes a large share of the lint job. Check before adopting: The cache key covers the runner OS, the tool version and every pinned revision the tool is built against.
- **[Linear](https://starsling.dev/ci-playbooks/linear#cache-tool-downloads)**: Use it when A pinned command-line tool or matrix leg downloads the same packages on every run. Check before adopting: OPT2’s recipe targets large binaries; here its version-pinned cache key applies to npm package downloads. Key the cache on every version that changes the download, and keep the step that installs or runs the tool.
- **[Shopify](https://starsling.dev/ci-playbooks/shopify#cache-browser-downloads)**: Use it when Browser downloads take a large share of a job's setup on every run. Check before adopting: A browser cache can take as long to restore as a fresh download; compare cold, warm and changed-lockfile runs before keeping it.
- **[Stripe](https://starsling.dev/ci-playbooks/stripe#reuse-downloaded-toolchains)**: Use it when Every CI job repeats a large toolchain download or installer bootstrap. Check before adopting: Key the reuse on exact version, OS and architecture, verify a published checksum, and install atomically so a partial download is never reused.

## Apply this technique

````text
Evaluate and apply this CI technique to my repository: Reuse downloaded tools across runs.

Cache versioned tools and browser downloads so jobs can restore them while retaining installation and repair checks.

Read the technique and its source-backed company examples: https://starsling.dev/ci-playbooks/techniques/cache-tool-downloads.md

Inspect this repository’s CI workflows, build and test commands, dependencies, and recent run timings. Identify where this technique applies and explain the expected benefit using this repository’s evidence.
Measure a baseline from recent comparable runs: elapsed time, queue time, runner minutes and failures where available. If data is unavailable, say what cannot be measured.
Compare relevant company approaches, checking prerequisites, platform differences and tradeoffs. Rank applicable options by evidence, fit and measurable opportunity; do not present company results as predictions for this repo.
Recommend the smallest safe change, show what checks and fallback paths remain, and ASK ME WHICH CHANGE TO APPROVE BEFORE EDITING ANY FILES.
Only after approval, work on a new feature branch, make one reversible change, and open a reviewable pull request. Never merge or push to a default or protected branch.
Keep required checks, test coverage, deployment and release behavior intact. Validate the change and compare equivalent runs where possible; report limitations and what should be monitored after merge.
````

## How companies used this technique

Read what each company changed and follow the original sources.

### Anthropic: Cache compiled lint tools between runs

Bun cached the cargo-dylint binaries on the tool version, and the dylint driver and mordant library on the version plus the pinned mordant revision. A cache hit skips only the install; the workspace check still runs on every change. The cache carried over when Bun folded its Rust lint jobs into one workflow.

Evidence: Estimate

A cold run takes about 6.5 minutes; the PR expects warm runs to take about a minute and a half (estimate). ([Source](https://github.com/oven-sh/bun/pull/38459))

Use it when: Installing or compiling a lint tool takes a large share of the lint job.

Before applying it: The cache key covers the runner OS, the tool version and every pinned revision the tool is built against.

[Read more in the Anthropic playbook](https://starsling.dev/ci-playbooks/anthropic#cache-lint-tools)

[Primary source](https://github.com/oven-sh/bun/pull/38459)

### Linear: Cache pinned tool and matrix downloads

The same SDK change caches the npm downloads of a version-pinned npx tool and of each smoke-test matrix leg, with keys that name the tool version or the matrix’s Node and TypeScript versions.

Evidence: Source PR/commit evidence

Use it when: A pinned command-line tool or matrix leg downloads the same packages on every run.

Before applying it: OPT2’s recipe targets large binaries; here its version-pinned cache key applies to npm package downloads. Key the cache on every version that changes the download, and keep the step that installs or runs the tool.

[Read more in the Linear playbook](https://starsling.dev/ci-playbooks/linear#cache-tool-downloads)

[Primary source](https://github.com/linear/linear/pull/1130)

### Shopify: Reuse browser downloads and keep the repair step

Checkout Kit caches Playwright Chromium in its default Linux cache directory, keyed by the runner's operating system and the web lockfile. The install command still runs after the restore, so it repairs a stale or partial cache and installs system dependencies.

Evidence: Source PR/commit evidence

Merged 2026-10-12; the cache step is on the default branch. ([Source](https://github.com/Shopify/checkout-kit/pull/972))

Use it when: Browser downloads take a large share of a job's setup on every run.

Before applying it: A browser cache can take as long to restore as a fresh download; compare cold, warm and changed-lockfile runs before keeping it.

[Read more in the Shopify playbook](https://starsling.dev/ci-playbooks/shopify#cache-browser-downloads)

[Primary source](https://github.com/Shopify/checkout-kit/pull/972)

### Stripe: Reuse a downloaded toolchain

Stripe Android replaced its Java installer with direct Temurin downloads for the configured version, OS and architecture, and reuses an existing install directory on later builds.

Evidence: Source PR/commit evidence

Use it when: Every CI job repeats a large toolchain download or installer bootstrap.

Before applying it: Key the reuse on exact version, OS and architecture, verify a published checksum, and install atomically so a partial download is never reused.

[Read more in the Stripe playbook](https://starsling.dev/ci-playbooks/stripe#reuse-downloaded-toolchains)

[Primary source](https://github.com/stripe/stripe-android/pull/12402)

## CI optimization is continuous work.

Apply this technique yourself, or use StarSling Runners for faster GitHub Actions and optional agent-driven optimization PRs, which teams on eligible paid plans can turn on.

[Get self-improving CI](https://starsling.dev/products/runners)

## Related techniques

### [Bake stable dependencies into runner images](https://starsling.dev/ci-playbooks/techniques/prebuild-runner-images)

Prepare versioned system dependencies and build downloads once in the runner image instead of installing them on every job.

2 implementations · 2 companies (Anthropic, Linear)

### [Cache package downloads and dependency stores](https://starsling.dev/ci-playbooks/techniques/reuse-package-downloads)

Restore package-manager downloads or dependency stores while keeping a locked install that validates the requested dependency graph.

7 implementations · 6 companies (DoorDash, Linear, Shopify, Spotify, Stripe, Uber)

### [Cache the directories the build actually uses](https://starsling.dev/ci-playbooks/techniques/cache-real-output-paths)

Align restored and saved cache paths with the tool’s real output directories so the next run can use the cached work.

2 implementations · 2 companies (OpenAI, Uber)

## Company Playbooks

### [Anthropic](https://starsling.dev/ci-playbooks/anthropic)

Run only affected tests

### [DoorDash](https://starsling.dev/ci-playbooks/doordash)

Run build and test in parallel, sharded across CI agents

### [Linear](https://starsling.dev/ci-playbooks/linear)

Benchmark the same job on faster hardware

### [Mastra](https://starsling.dev/ci-playbooks/mastra)

StarSling runners for the slowest test workflow

### [OpenAI](https://starsling.dev/ci-playbooks/openai)

Rank CI fixes by the minutes they save

### [Ramp](https://starsling.dev/ci-playbooks/ramp)

Move a CPU-bound test suite to a faster CPU

### [Shopify](https://starsling.dev/ci-playbooks/shopify)

Let an agent iterate against one CI metric

### [Spotify](https://starsling.dev/ci-playbooks/spotify)

Build arm64 on native arm64 runners

### [Stripe](https://starsling.dev/ci-playbooks/stripe)

Run only the tests a change can reach

### [Uber](https://starsling.dev/ci-playbooks/uber)

Build the merge-queue speculations most likely to be needed

## Related guides

Implementation guides for this technique.

### [Cache workflow dependencies](https://starsling.dev/best-practices/github-actions/cache-dependencies)

Choose dependency cache paths and keys for your package manager.

### [Cut repeated test setup](https://starsling.dev/best-practices/github-actions/cut-repeated-test-setup)

Share expensive setup at the scope your tests need.

### [Share setup steps across jobs](https://starsling.dev/github-actions/optimizations/avoid-duplicated-setup)

Centralize repeated setup definitions and remove duplicate or unused steps.

### [Optimize npm installs](https://starsling.dev/github-actions/optimizations/optimize-npm-install)

Cache npm dependencies and large downloads and remove unused tool installs.

### [Optimize pnpm installs](https://starsling.dev/github-actions/optimizations/optimize-pnpm-install)

Set up the pnpm store cache in the right order and scope recursive commands.
