quickstart →

Action download caching

Runners get the public actions a job uses from the S3 cache bucket in your VPC, each archive checked against the commit GitHub resolved.

Since v3.6.0, runners get the public actions a job uses (uses: owner/repo@ref) from your stack’s S3 cache bucket instead of downloading them one by one from GitHub when the job starts. There is nothing to enable, and nothing changes in your workflows.

Availability#

LinuxWindowsFlexFleet
Action download cachingYesYesYesYes

It works with github.com, and needs the RunsOn build of the GitHub Actions runner, which your stack installs on images that ship without a runner. Images with the stock runner download actions from GitHub as before.

How it works#

  1. GitHub resolves each action of the job to a commit, as usual.
  2. Before downloading them, the runner hands that list to the RunsOn agent, which looks every action up in the cache bucket at once. The archives it finds are placed where the runner looks first, so the runner skips those downloads.
  3. The runner downloads the other actions from GitHub as usual. Meanwhile, the agent stores them in the cache bucket for the stack’s next jobs.

If the cache bucket does not answer within 4 seconds, the runner downloads the actions from GitHub.

What to expect#

On a 2-vCPU runner, setting up a job that uses nine public actions took 1.37 s with the cache instead of 1.66 s (median of three jobs each). Cached actions also don’t depend on GitHub’s archive downloads, which occasionally stall: in the same tests, one download took 35 s.

What is cached#

  • Public actions from github.com repositories, at the commit GitHub resolved for the job, including the actions that composite actions use.
  • These still download from GitHub as before:
    • private and internal actions, which need the job’s credentials;
    • immutable action packages;
    • actions whose GitHub archive differs from their repository’s files: repositories that use export-ignore or export-subst in .gitattributes, that include Git LFS objects in archives, or that have submodules;
    • actions larger than 256 MiB.
  • Local actions (uses: ./path) and container images of Docker actions are not downloaded by the runner, so they are not affected.

Security#

  • The cache cannot change the code a job runs. Each entry stores the action’s commit object next to its archive. The agent uses an archive only after checking that the commit object matches the commit GitHub resolved, and that the archive’s files match that commit’s files. It then writes a fresh archive from the files it checked. An entry that fails the check is ignored, so the runner downloads that action from GitHub, and the agent replaces the entry.
  • Only public code is stored. Entries live under cache/actions/v1/ in the cache bucket, which every runner of the stack can read and write. The agent fetches actions from GitHub without credentials, so private actions are never stored. This holds on stacks with cache isolation too.

Retention#

Entries expire with the cache bucket’s lifecycle rule (S3CacheExpirationInDays in CloudFormation, cache_expiration_days in Terraform), 10 days by default.