GitLab CI/CD Associate study materials
GitLab CI/CD Associate study resources

GitLab CI/CD Associate: Caching and Artifacts

GitLab CI/CD Associate · Work through your exam, one topic at a time.

All guide sections

Caching and Artifacts

This domain tests the distinction between cache and artifacts, how cache keys select storage, and how artifacts travel between jobs.

The core distinction

  • Cache is a performance optimisation stored on the runner's cache backend. There is no guarantee it exists; treat every cache as potentially cold.
  • Artifacts are produced by a job, uploaded to GitLab, and guaranteed to be downloadable by later jobs and by users, subject to expire_in (default 30 days).

Caching node_modules or .m2 speeds up builds. Using cache to hand a compiled binary to a deploy job is wrong - that is what artifacts are for.

Cache keys

cache:key selects the bucket a job reads and writes. A static string shares one bucket across pipelines; $CI_COMMIT_REF_SLUG gives a per-branch bucket. cache:key:files hashes the contents of up to two files, commonly lockfiles, so the cache invalidates when dependencies change. cache:key:prefix prepends a string to a files-derived key, combining branch isolation with lockfile invalidation. cache:policy is pull-push (default), pull, or push; cache:fallback_keys lets a job try several keys in order.

Artifacts

artifacts:paths, artifacts:exclude, artifacts:name, artifacts:when (on_success default, on_failure, always), and artifacts:reports (JUnit, coverage, SAST, dependency scanning), which GitLab parses rather than merely stores.

By default a job downloads artifacts from all jobs in earlier stages. Once you use needs, it downloads only from the jobs it lists. dependencies: [] disables artifact download entirely; needs: [{job: build, artifacts: true}] is the explicit form.

Worked example

build:
  script: npm ci && npm run build
  cache:
    key:
      files: [package-lock.json]
      prefix: $CI_COMMIT_REF_SLUG
    paths: [node_modules/]
    policy: pull-push
  artifacts:
    paths: [dist/]
    expire_in: 1 week

Reasoning: the cache key changes when package-lock.json changes or the branch changes, so stale node_modules are not reused. The artifact is what a later deploy job consumes, and it disappears after a week. If a second job only reads the cache, give it policy: pull so it does not re-upload an identical archive.

Traps

  • Assuming cache is shared between runners or projects - it is scoped to the runner's backend and the key.
  • Pointing cache:key:files at a file that does not exist in the repository.
  • Forgetting that needs narrows artifact downloads, so a job silently loses a file it used to receive.
  • Setting expire_in shorter than the interval a downstream scheduled job needs the artifact.