Reduce build times with sccache#1905
Conversation
Update related-pr to point to PR 1905 for experiment tracking.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #1905 +/- ##
===========================================
- Coverage 79.17% 79.10% -0.07%
===========================================
Files 326 326
Lines 22801 22804 +3
Branches 22801 22804 +3
===========================================
- Hits 18052 18039 -13
- Misses 4494 4501 +7
- Partials 255 264 +9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Update related-pr to point to PR 1905 for experiment tracking.
Cold build: 479.44 s (5.52 % cache hits, 133 write errors) Warm-after-change: 153.86 s (6.96 % cache hits) Key finding: the warm-after-change speedup comes from Cargo's own dependency tracking, not from sccache. Cross-run cache test (Run 2) is still pending.
Cross-run cache test confirms sccache GHA backend works well: - Cold with cache restore: 192.21 s (93.38 % hits, vs 479.44 s without) - Warm-after-change: 137.35 s (93.48 % hits) - Task 3a complete Proceeding to Task 3b: sccache inside Docker build.
Experiment 1: sccache with BuildKit cache mount works within single build Experiment 2: BuildKit cache mounts are stage-scoped, not shared across stages Experiment 3: SCCACHE_GHA_ENABLED=true fails hard without GHA creds; local disk fallback works Key finding: GHA backend must be passed into Docker via --secret-env. The Containerfile must NOT hardcode SCCACHE_GHA_ENABLED=true as it breaks local builds.
Three local Docker experiments conducted to determine best sccache integration strategy: - Exp 1: BuildKit cache mounts work within single build - Exp 2: Cache mounts are stage-scoped, not shared across stages - Exp 3: SCCACHE_GHA_ENABLED=true fails hard without GHA creds Decision: Use B2 (GHA backend passed via --secret-env into Docker build) instead of B1 (mount host cache), which was found infeasible.
- Created Containerfile.sccache-experiment with sccache in chef stage - Built chef stage locally: sccache 0.15.0 + cargo-chef verified - Remaining Task 3b items (GHA workflow, cross-run test) pending as they require GitHub Actions runner access - Updated ISSUE.md with current progress checkboxes
Reviewed Docker cache optimization docs, BuildKit docs, GHA cache backend docs, and sccache docs. Key insight: container.yaml already uses cache-from/ cache-to: type=gha, mode=max for BuildKit layer caching. sccache would be a second caching layer inside Docker layers — only helpful when Cargo.lock changes but individual crate sources don't. Decision remains B2 (GHA backend via --secret-env) but added github-token to mitigate cache API throttling risk. Strategy question: whether sccache inside Docker adds value beyond the already- working BuildKit layer cache will be answered by the experiment data.
- Containerfile.sccache-experiment: ARG for GHA credentials - New experiment-sccache-docker.yaml (Docker build + E2E) - Local Docker stage timings: third-party deps 52.75 s - Need GHA runner for cold/warm comparison Note: build-args for GHA tokens trigger Docker security warnings. Acceptable for experiment branches. Production would use --secret-env.
Applied sccache to all workflow jobs that compile Rust directly on GHA runners: - testing.yaml: unit + docker-e2e jobs - os-compatibility.yaml: build job (6 matrix combinations) - db-compatibility.yaml: mysql + postgres jobs - coverage.yaml: report job - db-benchmarking.yaml: sqlite3 + mysql + postgres jobs ADR docs/adrs/20260612000000_adopt_sccache_for_ci_bare_builds.md documents the decision: - Adopt sccache for bare CI builds (93.38 % hit rate, -60 % build time) - Reject sccache for local development (cold: +22 % slower) - Reject sccache for Docker builds (no benefit on GHA runners) Workflow files reference the ADR via '# adr:' comments.
Added guidance to semantic-skill-link-convention.md for: - Cross-referencing ADRs using frontmatter related-artifacts with issue #N - Linking workflows to ADRs via '# adr:' comments - Stability warning about issue spec file paths vs issue numbers
Added explanation that YAML frontmatter (--- delimiter) would create a second YAML document, and that the workflow schema rejects unknown top-level keys.
f7bec0b to
b093328
Compare
Updated run-pre-commit-checks, run-pre-push-checks, and commit-changes skills to instruct AI agents to set TORRUST_GIT_HOOKS_LOG_DIR=.tmp so per-step log files stay inside the workspace (git-ignored .tmp/) instead of /tmp.
Repo cache at 13.03 GB / 10 GB (over limit). sccache proved superior (93.38 % hit rate vs ~0 % for Swatinem). Removing Swatinem/rust-cache to free cache space and avoid eviction of sccache entries. Removed from: testing.yaml (unit + docker-e2e), db-compatibility.yaml (mysql + postgres), coverage.yaml, db-benchmarking.yaml (sqlite3 + mysql + postgres)
There was a problem hiding this comment.
Pull request overview
This PR documents and operationalizes the outcome of issue #1726’s sccache investigation: rejecting sccache for local development and Docker-based CI builds, while adopting it for “bare” (non-Docker) GitHub Actions jobs to reduce repeat-run compile time via the GHA backend.
Changes:
- Adds benchmark reports + analysis docs (local A/B, GHA bare build results, Docker build experiment results) and an ADR capturing the final decision.
- Updates multiple CI workflows to replace
Swatinem/rust-cachewithmozilla-actions/sccache-action+RUSTC_WRAPPER=sccachefor bare Rust compilation steps. - Archives experiment workflows / Containerfile variants and supporting Docker experiments under
contrib/dev-tools/experiments/.
Reviewed changes
Copilot reviewed 37 out of 41 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| project-words.txt | Adds new spellcheck dictionary words used by the new docs/CI experiment writeups. |
| docs/skills/semantic-skill-link-convention.md | Documents how to semantically link long-lived artifacts (ADRs/workflows/issues), including ADR references from workflows. |
| docs/issues/open/1726-1840-workflow-performance-sccache/sccache-a-b-report.md | Adds the local A/B benchmark report with commands, timings, and sccache stats. |
| docs/issues/open/1726-1840-workflow-performance-sccache/Q-and-A.md | Adds a Q&A log for reviewer questions and evidence-driven answers. |
| docs/issues/open/1726-1840-workflow-performance-sccache/ISSUE.md | Updates the research spec with completed tasks, results, and the final recommendation/decision trail. |
| docs/issues/open/1726-1840-workflow-performance-sccache/experiment-results-gha.md | Captures GHA bare-build experiment timings/stats for cross-run sccache caching. |
| docs/issues/open/1726-1840-workflow-performance-sccache/experiment-docker-gha-results.md | Captures GHA Docker-build experiment results and conclusions. |
| docs/issues/open/1726-1840-workflow-performance-sccache/compile-hotspot-analysis.md | Updates baseline timings and revises recommendations based on measured A/B data. |
| docs/adrs/20260612000000_adopt_sccache_for_ci_bare_builds.md | New ADR formalizing “adopt for bare CI only; reject locally and for Docker builds”. |
| contrib/dev-tools/experiments/sccache-docker/test-crate/src/main.rs | Test crate used by Docker/sccache experiments. |
| contrib/dev-tools/experiments/sccache-docker/test-crate/Cargo.toml | Test crate manifest for Docker/sccache experiments. |
| contrib/dev-tools/experiments/sccache-docker/test-crate/Cargo.lock | Locked dependency set for reproducible Docker/sccache experiments. |
| contrib/dev-tools/experiments/sccache-docker/README.md | Explains experiment structure, how to run, and how results are tracked. |
| contrib/dev-tools/experiments/sccache-docker/Dockerfile.test | Minimal BuildKit-cache-mount Dockerfile to validate sccache behavior in-container. |
| contrib/dev-tools/experiments/sccache-docker/04-gha-workflow-experiments/REPORT.md | Summarizes the GHA workflow experiments and the key fixes discovered. |
| contrib/dev-tools/experiments/sccache-docker/04-gha-workflow-experiments/experiment-sccache-docker.yaml | Archived workflow used to benchmark sccache inside Docker builds on GHA. |
| contrib/dev-tools/experiments/sccache-docker/04-gha-workflow-experiments/experiment-sccache-bare-build.yaml | Archived workflow used to benchmark bare cargo build --release with sccache on GHA. |
| contrib/dev-tools/experiments/sccache-docker/04-gha-workflow-experiments/Containerfile.sccache-experiment | Archived Containerfile variant used to test sccache inside Docker build stages. |
| contrib/dev-tools/experiments/sccache-docker/03-gha-backend/src/main.rs | Test program for validating sccache behavior under “GHA backend enabled” scenarios. |
| contrib/dev-tools/experiments/sccache-docker/03-gha-backend/REPORT.md | Documents the “fails hard without creds” behavior and the corrected approach. |
| contrib/dev-tools/experiments/sccache-docker/03-gha-backend/Dockerfile | Docker experiment to validate secret-based credential passing strategy. |
| contrib/dev-tools/experiments/sccache-docker/03-gha-backend/Cargo.toml | Manifest for the GHA-backend experiment crate. |
| contrib/dev-tools/experiments/sccache-docker/03-gha-backend/Cargo.lock | Locked deps for the GHA-backend experiment crate. |
| contrib/dev-tools/experiments/sccache-docker/02-multi-stage/src/main.rs | Test program for multi-stage build experiments. |
| contrib/dev-tools/experiments/sccache-docker/02-multi-stage/REPORT.md | Documents findings about cache-mount scoping across Docker stages. |
| contrib/dev-tools/experiments/sccache-docker/02-multi-stage/Dockerfile | Multi-stage Docker experiment mirroring the production Containerfile structure. |
| contrib/dev-tools/experiments/sccache-docker/02-multi-stage/Cargo.toml | Manifest for multi-stage experiment crate. |
| contrib/dev-tools/experiments/sccache-docker/02-multi-stage/Cargo.lock | Locked deps for multi-stage experiment crate. |
| contrib/dev-tools/experiments/sccache-docker/01-basic-build/src/main.rs | Test program for the basic BuildKit cache-mount experiment. |
| contrib/dev-tools/experiments/sccache-docker/01-basic-build/REPORT.md | Records timings/stats and conclusions for the basic Docker experiment. |
| contrib/dev-tools/experiments/sccache-docker/01-basic-build/Dockerfile | Basic Docker experiment verifying sccache + cache mounts. |
| contrib/dev-tools/experiments/sccache-docker/01-basic-build/Cargo.toml | Manifest for basic-build experiment crate. |
| contrib/dev-tools/experiments/sccache-docker/01-basic-build/Cargo.lock | Locked deps for basic-build experiment crate. |
| .github/workflows/testing.yaml | Enables sccache GHA backend for bare compilation steps; removes rust-cache in affected jobs. |
| .github/workflows/os-compatibility.yaml | Enables sccache for cross-run caching on OS compatibility builds. |
| .github/workflows/db-compatibility.yaml | Enables sccache for DB compatibility jobs to reduce repeat-run compile time. |
| .github/workflows/db-benchmarking.yaml | Enables sccache for DB benchmarking jobs; removes rust-cache steps. |
| .github/workflows/coverage.yaml | Enables sccache in coverage job (keeping CARGO_INCREMENTAL=0 from job env). |
| .github/skills/dev/git-workflow/run-pre-push-checks/SKILL.md | Updates instructions to set TORRUST_GIT_HOOKS_LOG_DIR=.tmp for agents. |
| .github/skills/dev/git-workflow/run-pre-commit-checks/SKILL.md | Same .tmp logging guidance for pre-commit checks. |
| .github/skills/dev/git-workflow/commit-changes/SKILL.md | Same .tmp logging guidance for commit workflow. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix project-words.txt alphabetical order (endgroup/endianness) - Fix Q&A: clarify token scope ≠ cross-run block (Task 3a proved 93% hits work) - Fix experiment-results-gha: 'incremental compilation' → 'dependency fingerprinting' - Fix experiment-results-gha: remove TBD placeholder table at end - Fix ISSUE.md: replace [- ] with [ ] ~strikethrough~ for GitHub task list compatibility - Fix sccache-a-b-report: mark cargo install sccache section as skipped - Fix testing.yaml ADR comment to mention Swatinem removal
…and tracker-client - packages/udp-server/: box large HandlerError tuple to fix clippy::result_large_err - packages/tracker-core/: suppress clippy::extra_unused_lifetimes on #[automock] traits - console/tracker-client/: box large Error variant and fix dead match arm - docs/issues/open/1726-1840-workflow-performance-sccache/: fix typo in checkbox PR: torrust#1905
|
ACK 3538730 |
Evidence-driven research for issue #1726.
Summary
This PR investigates whether sccache can reduce CI build times for the Torrust Tracker workspace. After controlled benchmarks in three contexts — local development, GHA bare builds, and GHA Docker builds — the final decision is documented in ADR
docs/adrs/20260612000000_adopt_sccache_for_ci_bare_builds.md.Final decisions:
Changes
Production CI (5 workflow files)
.github/workflows/testing.yaml— add sccache tounit,test-doc,clippy,fmtjobs.github/workflows/os-compatibility.yaml— add sccache tobuildjob.github/workflows/db-compatibility.yaml— add sccache tobuildjobs.github/workflows/coverage.yaml— add sccache, remove Swatinem/rust-cache.github/workflows/db-benchmarking.yaml— add sccache, remove Swatinem/rust-cacheExperiment artifacts (archived under
contrib/dev-tools/experiments/sccache-docker/)experiment-sccache-bare-build.yaml,experiment-sccache-docker.yamlContainerfile.sccache-experimentfor sccache-in-Docker experimentsDocumentation
docs/adrs/20260612000000_adopt_sccache_for_ci_bare_builds.mddocs/issues/open/1726-1840-workflow-performance-sccache/ISSUE.md— all tasks checked completesemantic-skill-link-convention.md, git hook skills updated (TORRUST_GIT_HOOKS_LOG_DIR=.tmp)Drive-by fixes
clippy::result_large_errby boxing largeHandlerErrortuple inpackages/udp-server/src/handlers/clippy::extra_unused_lifetimeson#[automock]traits inpackages/tracker-core/src/databases/traits/console/tracker-client/src/console/clients/Checklist
See full spec:
docs/issues/open/1726-1840-workflow-performance-sccache/ISSUE.md