Caching
Every runner gets a persistent /cache volume. It survives across runner
generations: a fresh ephemeral container picks up the warm cache the previous one
left behind. A GitHub-hosted runner has nothing persistent attached, so this is
where workflows for Runaway diverge.
Cache volumes belong to the host, not the workload. A workload selects one with an optional cache key.
Pre-wired ecosystem caches
Section titled “Pre-wired ecosystem caches”Runaway points yarn, npm, pnpm, pip, Go modules, and cargo at the /cache
volume with no configuration. Installs land on the persistent volume and the next
run reuses them.
Skip GitHub’s Actions Cache for tool binaries
Section titled “Skip GitHub’s Actions Cache for tool binaries”On a GitHub-hosted runner, actions/cache@v4 and actions/setup-node’s cache:
input make sense: the runner is thrown away with nothing persistent attached, so
caching means tar + compress + round-trip through GitHub’s Cache service.
On a Runaway runner that round-trip is slower than reading the already-warm
local /cache volume. Point your tools at /cache instead.
Drop the cache: input — the pnpm store already lives on the volume:
# No `cache: pnpm` — the store already persists on /cache.- uses: actions/setup-node@v4 with: node-version: 22Put browser binaries and other heavy tool downloads on the volume directly:
env: PLAYWRIGHT_BROWSERS_PATH: /cache/ms-playwrightWith the path on /cache, playwright install no-ops on warm runs instead of
re-downloading browsers every job.
How the volume is resolved
Section titled “How the volume is resolved”The effective /cache volume is resolved per host, org, and cache key:
- No key — one shared cache per organization on that host, named
runaway-cache.<org-slug>. - A key — a separate warm cache, named
runaway-cache.<org-slug>.<key>.
Same-org workloads that use the same key share a warm cache on a host. Different organizations never share a cache — the volume is org-scoped, so private packages can’t leak across orgs.
Managing caches
Section titled “Managing caches”Cache volumes are managed from the Cache tab on a host’s detail page —
/cache is a physically distinct Docker volume on each host, so each host shows
its own volumes, never a cross-host sum. Inspect a volume’s size, see the
per-ecosystem breakdown, and purge from there. The purge action is gated on no
live runners using the volume, so you can’t wipe a cache out from under a
running job.
Isolated runners and the cache volume
Section titled “Isolated runners and the cache volume”A workload on a nested isolated runtime gets
a fresh inner Docker daemon per runner, so Docker layer cache does not
carry across generations — that matches github-hosted semantics. The /cache
filesystem volume still bind-mounts in, so your ecosystem and tool caches
survive exactly as they do on the shared-daemon runtime.