Home / Alt manpages / gh-cache(1)

  • gh-cache(1)
  • User command
  • linux

Audit and Remove GitHub Actions Caches with gh cache

You will finish with a repeatable way to inspect GitHub Actions caches for a repository and remove one cache, a matching key on one ref, or all caches for a specific ref. The examples use GitHub CLI 2.87.3, the gh executable installed at /home/linuxbrew/.linuxbrew/bin/gh on this machine. Allow about ten minutes for an audit, plus time to decide whether a cache is safe to remove.

You need an authenticated gh session and access to the target repository. Cache listing is read-only. Deletion changes remote repository state, requires the repo authorisation scope, and cannot be undone through gh cache. No command in this guide needs sudo.

1. Confirm the installed command

Check the binary and its version before relying on option names. This is an ordinary local check:

$ command -v gh
/home/linuxbrew/.linuxbrew/bin/gh
$ gh --version
gh version 2.87.3 (2026-02-23)

The Ubuntu package database on this host also contains a package named gh, but the command found first is the Homebrew binary above. That distinction matters when a flag behaves differently on another machine. Ask the binary you will actually run for the cache help:

$ gh cache --help
Work with GitHub Actions caches.

AVAILABLE COMMANDS
  delete:  Delete GitHub Actions caches
  list:    List GitHub Actions caches

Checkpoint

If the version or executable is not the one you expect, stop here and fix your PATH before inspecting or deleting anything.

2. Select the repository explicitly

From a checkout of the intended repository, gh can infer the owner and repository from Git. An explicit repository is safer in a script or when your current directory is not the checkout:

$ REPO='OWNER/REPOSITORY'
$ gh cache list --repo "$REPO"

Replace both placeholder words with the real owner and repository. GitHub Enterprise hosts use the documented form HOST/OWNER/REPO. Keep the value quoted so shell punctuation cannot change the argument.

A successful list prints cache rows. An authentication or permission error means the audit has not happened; do not respond by adding sudo. Check the account and host with gh auth status, then retry the list command.

3. Make a focused cache inventory

gh cache list fetches at most 30 caches by default, sorted by last access with the newest first. Make the selection visible when looking for storage that has not been used recently:

$ gh cache list --repo "$REPO" \
    --sort last_accessed_at --order asc --limit 100

The limit is the maximum number fetched, not a guarantee that the repository has that many caches. The table includes the cache key, ref, size, creation time and last access time. A cache key is not necessarily unique across refs, so record both the key and ref before deletion.

Filter by a key prefix when a workflow family is known:

$ gh cache list --repo "$REPO" --key 'npm-linux-'

For a branch, use the complete ref form. Do not pass only the short branch name:

$ gh cache list --repo "$REPO" \
    --ref 'refs/heads/feature/example' \
    --json key,id,ref,sizeInBytes,lastAccessedAt \
    --jq '.[] | [.id, .key, .ref, .sizeInBytes, .lastAccessedAt] | @tsv'

Checkpoint

Save or copy the resulting ID, key and ref. If the output is empty, the filter found no matching cache; it does not prove that the repository has no caches at all. Run an unfiltered list before changing the filters.

4. Delete one identified cache

Deletion is the irreversible step. Recheck the repository, ID and key immediately before running it. Prefer an ID copied from the inventory, because a key can match more than one cache:

$ CACHE_ID='123456789'
$ gh cache delete "$CACHE_ID" --repo "$REPO"

The command asks GitHub to remove that cache. The exact confirmation text can vary, but a successful command returns exit status 0. Verify the result by looking up the ID or listing the same filter again:

$ gh cache list --repo "$REPO" --json id,key,ref \
    --jq '.[] | select(.id == 123456789)'

No matching JSON output means the ID is no longer in the returned list. If deletion fails, do not repeat it blindly: check the error, authorisation scope and repository target first.

5. Delete a key on one ref

Use a key and full ref when the same workflow key appears on several branches or pull requests:

$ CACHE_KEY='npm-linux-node-22'
$ CACHE_REF='refs/heads/feature/example'
$ gh cache delete "$CACHE_KEY" --ref "$CACHE_REF" --repo "$REPO"

This changes the matching cache for that ref. It does not delete every cache whose key merely looks similar. List with the same key and ref afterwards to confirm what remains.

6. Remove all caches only with a narrow boundary

Warning

--all deletes every cache in the selected repository unless you also supply --ref. This can make the next Actions runs slower while caches are rebuilt. There is no restore command in gh cache.

If the intended operation really is to clear one branch or pull request, include its complete ref:

$ CACHE_REF='refs/pull/42/merge'
$ gh cache delete --all --ref "$CACHE_REF" --repo "$REPO"

List that ref again to verify it is empty. For an intentionally broad cleanup, omit --ref only after an unfiltered inventory and a second-person review of the repository name. If no caches exist, the plain --all form returns exit code 1; add --succeed-on-no-caches when an empty result should count as success in a script.

Common traps and recovery

A short branch name is not the documented cache ref format. Use refs/heads/branch-name for a branch and refs/pull/number/merge for a pull request. A cache key prefix can also produce more than one result, so inspect the IDs and refs rather than deleting the first row.

Cache deletion has no undo operation. Recovery means allowing a later workflow run to recreate the cache, or restoring the workflow's cache configuration if that was the real mistake. If you deleted a cache while a workflow was running, let the job finish and check its logs; deletion affects the stored cache, not files already present in a runner.

Done means

  • You confirmed the executable and version used by the shell.
  • You listed the intended repository, using an explicit --repo value where context could be confusing.
  • You recorded the exact cache ID, key and ref before deletion.
  • You used a full ref when removing caches for one branch or pull request.
  • You verified the result with a fresh list command.
  • You treated --all as a destructive operation and know that deleted caches must be rebuilt by future workflow runs.