What's changed: New GH-200 Chapter 5 (security best practices = script-injection mitigation, GITHUB_TOKEN least privilege vs PAT, OIDC cloud federation, SHA pinning/trustworthy actions/usage policies, attestations/provenance (SLSA), environment approval gates; performance/cost optimization = actions/cache, retention (REST API), matrix size/max-parallel, concurrency+cancel-in-progress, paths/branches filters, if conditions, runner sizing)
5.2Optimizing Performance and Cost
Understand efficiency via caching and artifact retention, applying retention policies via REST APIs, and strategies for scaling and cost-optimizing workflows—concurrency, matrix size, concurrency groups, runner selection, conditionals, and path/branch filters.
GitHub Actions usage is billed by execution minutes and storage (artifacts/cache). GH-200 tests optimizing for faster and cheaper runs without sacrificing results. The levers fall into "reduce waste (avoid unneeded runs/re-downloads)" and "tune parallelism and retention."
5.2.1Caching and retention
Caching (actions/cache)—avoiding dependency re-fetches—is the most effective speed-up (Chapter 1). Artifacts and logs have a retention period; keeping them longer increases storage billing—review defaults and shorten via retention-days at upload to cut cost. These retention policies are also applicable/inspectable via the REST API, enabling org-wide auto-deletion of stale data. Note caches have free-tier/size limits and old caches are evicted automatically.
5.2.2Matrix size and parallelism
matrix is convenient, but more combinations inflate execution minutes (cost). Limit to the OS×versions you truly need, trim with exclude, and add only exceptions with include. Cap concurrency with max-parallel to manage runner capacity and cost. For normal CI that doesn’t need failure isolation, fail-fast: true (default) cancels early to avoid wasted runs.
5.2.3Reducing redundant runs with concurrency
Rapid repeated pushes to the same branch/PR keep stale runs going. Setting a concurrency group with cancel-in-progress: true auto-cancels in-progress runs in the same group when a new run starts, validating only the latest commit and saving cost. For things you want serialized (like deploys), you can queue instead of cancel.
5.2.4Cutting waste with filters and conditionals
The biggest saving is to not trigger runs you don’t need. Use paths/paths-ignore and branches/branches-ignore filters on push/pull_request to, e.g., skip CI for docs-only changes. Skip unneeded work with if conditions on jobs/steps, and run heavy jobs only when needed. Choose a runner sized to requirements (standard vs larger), avoiding over-provisioning to optimize cost.
| Goal | Lever |
|---|---|
| Avoid dependency re-fetch | actions/cache |
| Don’t trigger unneeded runs | paths/branches filters, if conditions |
| Stop stale runs | concurrency + cancel-in-progress |
| Control matrix cost | exclude, max-parallel, keep minimal |
| Control storage billing | retention-days, retention policy (REST API) |
Common: (1) Fastest speed-up = actions/cache (avoid dependency re-fetch). (2) concurrency + cancel-in-progress auto-cancels stale runs (validate only the latest). (3) paths/branches filters and if conditions avoid unneeded runs. (4) Keep matrix minimal + exclude + max-parallel to control cost. (5) Shorten storage via retention-days / retention policy (REST API). (6) Choose a right-sized runner, avoiding over-provisioning.
Watch out: (1) Cache (speed-up, regenerable) ≠ artifacts (outputs to keep)—don’t expect long-term storage from cache. (2) concurrency cancel-in-progress may be unsuitable for deploys (side effects of mid-cancel)—serialize via queueing. (3) Blindly growing the matrix spikes cost. (4) Over-skipping via filters/if reduces coverage—balance it. (5) Too-short retention deletes logs/artifacts you still need.
5.2.5Section summary
- Speed up deps with actions/cache; control storage billing via retention-days/retention policy (REST API)
- concurrency + cancel-in-progress auto-cancels stale runs to validate only the latest
- paths/branches filters and if conditions avoid unneeded runs; keep matrix minimal + exclude + max-parallel
- Right-size runners and avoid over-provisioning (balance speed and results)
Sign in to track progress — Log in.
Quick check
(just a quick review)Q1. Each rapid push to a PR keeps stale CI runs going, wasting runner capacity and cost. What is the most appropriate fix?
Q2. Heavy CI (build/test) runs even for docs-only (*.md) changes. What is the simplest saving?
Q3. Builds re-download npm dependencies each time, which is slow and consumes minutes. What is the most effective speed-up?
Q4. Artifact storage billing is rising. Which is an appropriate way to reduce cost?
Q5. A bloated OS×version test matrix spiked costs. How do you control cost while preserving results?
Q6. Which correctly states the difference between cache and artifacts (optimization view)?
Keep track of your progress
The full study guide is free to read. Sign up free to practice with the question bank, track what you have read, review your mistakes, and highlight passages.

