---
title: "GitHub runners and Cache: CI that keeps up with your agents · Frazer"
description: "GitHub runners give each GitHub Actions job a fresh microVM on your servers or ours, next to a cache that already holds what the job needs. Agent pull requests get their own lane."
url: https://frazer.ai/runners/github
index: https://frazer.ai/llms.txt
tokens: 2718
---

> For agents: every page on frazer.ai is indexed at https://frazer.ai/llms.txt.

# GitHub runners and Cache: CI that keeps up with your agents · Frazer

**GitHub runners**  frazer.ai

# CI that keeps up with your agents.  
Change one line.

GitHub runners give each GitHub Actions job a fresh microVM on your servers or ours, next to a cache that already holds what the job needs. Agent pull requests get their own lane, so a thousand of them never starve the one you are waiting for.

[Connect GitHub](https://frazer.ai/start?product=runners) [Read the runner docs](https://frazer.ai/docs/runners/github)

Isolation

A fresh microVM per job, destroyed after

Where

Your servers, or the Frazer fleet by the second

Cache

Already warm: dependencies, build outputs, a disk per repository

Agents

Their own lane, cap and daily budget

```
# .github/workflows/ci.yml
jobs:
  test:
-   runs-on: ubuntu-latest
+   runs-on: frazer-8c
    steps:
      - uses: actions/checkout@v5
      - run: go test ./...      # caches already wired
```

```
# .github/workflows/ci.yml
jobs:
  test:
-   runs-on: ubuntu-latest
+   runs-on: >-   # bot PRs: agent lane · pushes: main
+     frazer-8c${{ github.event_name == 'pull_request' &&
+     (github.event.pull_request.user.type == 'Bot' &&
+     '-agent' || '') || '-main' }}
```

```
# .github/workflows/release.yml
jobs:
  release:
-   runs-on: ubuntu-latest
+   runs-on: frazer-16c-release
    steps:
      - uses: actions/checkout@v5
      - run: make release      # reads dependencies only
```

00 · A job, explained Fig. 1 · product UI, demo organization

*A job page in the Frazer console: checkout-api · test passed in 2 m 43 s on frazer-8c in the agent lane; the time split into wait, start, cache, steps and upload, compared with the job’s 7-day median, each step with its cache result, and the results offered as records over API and MCP.*

Fig. 1: a job page in the Frazer console, product UI with a demo organization.

A

**Five phases, every job** Wait, start, cache, steps and upload, from GitHub’s timestamps and the VM’s own agent.

B

**Why slower, from records** Compared with the job’s median; causes named from events, never guessed.

C

**Every cache restore shown** Which tier answered, how many bytes, how long, and who may write.

D

**Results as data** The Reviewer, the verifier and agents read results instead of scraping logs.

01 · Why your CI is slow Fig. 2

## Most CI time is not your tests.  
It is waiting, fetching and rebuilding.

**Fig. 2** Where a job’s time goes, before and after illustrative

1.  ### Waiting for a runner
    
    Runner fleets are sized for an average day; a burst of pull requests queues behind them.
    
    Queue-driven scaling with a learned warm pool and overflow to the fleet; overcommit on your own servers.
    
2.  ### A cold machine every time
    
    Each job boots, installs toolchains and clones the repository from zero.
    
    Warm microVMs from a signed image ring; a copy-on-write disk per repository with git objects and toolchains.
    
3.  ### Downloading the same things
    
    Every job fetches the same modules, packages and images from the internet.
    
    A dependency proxy at the site, verified by checksums and lockfiles, shared by every job.
    
4.  ### Rebuilding what did not change
    
    No shared build cache, or one anybody can write to.
    
    Content-addressed build outputs shared under write rules: protected branches write, pull requests read.
    
5.  ### A cache that is far away or full
    
    A remote cache with a size cap is slow to restore and evicts what you need.
    
    A cache on the same servers, with quotas you set and fail-open behavior: an outage is a miss, never a failure.
    
6.  ### Agents flooding the queue
    
    Hundreds of agent pull requests a day land in the same queue as people’s.
    
    Lanes with floors, caps and a daily budget that holds agent jobs instead of failing them.
    

02 · Built for agent pull request volume Fig. 3

## A thousand agent PRs a day.  
And yours still runs first.

Designed for 1,000+ agent pull requests a day per organization. Agents get their own lane below people, a floor so they never stop, a cap so they never take over, and a daily budget that holds their jobs in the queue rather than failing them.

**Fig. 3** Lanes, floors, caps and budgets in one pool default policy

03 · Frazer Cache Fig. 4

## One cache for CI, boxes and agents.  
Shared widely, written carefully.

The same cache serves your runners, your engineers’ devboxes, agent sandboxes and serverless builds, so nothing is downloaded or compiled a hundred times. Only trusted builds write what others read, every entry is signed by its writer, and a poisoned entry is purged by writer in one command.

**Fig. 4** Four tiers, one write-trust model

-   Go modules
-   GOCACHEPROG
-   Docker · BuildKit
-   actions/cache
-   npm · pnpm
-   PyPI · uv
-   Bazel REAPI
-   Gradle
-   Turborepo · Nx
-   sccache

04 · Secure by construction

## Fresh, isolated, short-lived.  
Every job.

-   ### A microVM per job
    
    Its own kernel and Docker; never reused; nothing survives the job.
    
-   ### No long-lived tokens
    
    Just-in-time runner registration; registry, secrets and cache through OIDC.
    
-   ### Egress you can read
    
    An allow-list per pool, with a log of every destination.
    
-   ### Forks stay outside
    
    Fork pull requests run only on untrusted pools; pull\_request\_target is refused on trusted ones.
    
-   ### Watched
    
    Wedged runners are destroyed and the job re-run once; a second wedge opens an incident.
    
-   ### Same bytes everywhere
    
    One workspace template builds the runner image, the devbox and the agent sandbox; “Debug in a box” opens a failed job.
    

05 · Compared with what you run today

## The speed of hosted runners.  
The control of your own.

GitHub runners compared with a typical hosted runner and a typical self-hosted runner

|  | GitHub runners on Frazer | Typical hosted runner | Typical self-hosted runner |
| --- | --- | --- | --- |
| A fresh VM for every job | Yes, a microVM | Usually | Rarely |
| Runs on hardware you own | Yes, or the Frazer fleet | No | Yes |
| A cache beside the runner, with quotas you set | Yes, four tiers | Remote, size-capped | Build it yourself |
| Rules for who may write the shared cache | Yes, by writer identity | By branch scope | Build it yourself |
| Lanes, caps and budgets for agent pull requests | Yes | No | Build it yourself |
| Why a job was slower, from records | Yes | Timestamps only | Build it yourself |
| Who patches images, scales and watches runners | Frazer | The vendor | Your team |
| Per-minute fee on your own servers | None | Not applicable | Varies by vendor |

Generic categories, not named products. No speed or cost figures here: the job page shows yours, from records.

-   ### GitHub Actions
    
    github.com and GitHub Enterprise Server
    
-   ### GitLab
    
    SaaS and self-managed runners
    
-   ### Buildkite
    
    An agent per job
    
-   ### Forgejo and Gitea
    
    Ephemeral runners
    

06 · Pricing

## No per-minute fee  
on servers you own.

On your servers, GitHub runners and Frazer Cache are part of the per-core server fee. On the Frazer fleet you pay $0.045 per vCPU-hour with 4 GiB per vCPU, billed per second, with no minimum and no rounding up.

[See every price](https://frazer.ai/pricing)

Your servers

**Included** in $1.50 per physical core per month

frazer-4c

4 vCPU · 16 GiB · $0.003 per minute

frazer-8c

8 vCPU · 32 GiB · $0.006 per minute

frazer-16c

16 vCPU · 64 GiB · $0.012 per minute

GPU runners

The fleet GPU price plus a 4 vCPU runner

Cache, your servers

**Included** · uses your disks

Cache, fleet

$0.012 per GiB-month; no request or in-site egress fee

07 · For repositories on Fir

## Code on Fir?  
Frazer CI runs it natively.

GitHub runners runs GitHub Actions jobs for repositories that stay on GitHub. Repositories on Fir, Frazer’s version control, use Frazer CI instead: every task is keyed by the hash of its inputs, so a task whose inputs did not change is answered from its signed result before any machine starts. The tasks that run get their own microVM on Frazer Runners.

The two products share the price and the bill, never a host, a pool or a queue.

[Frazer CI](https://frazer.ai/ci) [Fir, our version control](https://frazer.ai/source)

GitHub runners compared with Frazer CI on Frazer Runners

|  | GitHub runners | Frazer CI on Frazer Runners |
| --- | --- | --- |
| For | Repositories on GitHub | Repositories on Fir |
| Unit of work | A GitHub Actions job | A task with declared inputs, outputs and a key |
| What runs | Every queued job starts a machine | Only tasks whose inputs changed; the rest are cache hits |
| Source | A checkout into a warm disk | A read-only projection of the task’s inputs, no checkout |
| Results | Job records with phases and tests | A signed result per task, read by the merge policy |
| Price | $0.045 per vCPU-hour, per second | The same rate; a cache hit costs nothing |

Questions

## GitHub runners, answered.

Do I have to change my workflows?

One line. Install the Frazer GitHub Runners app on your GitHub organization, create a pool and change `runs-on` to a Frazer size such as `frazer-8c`. `actions/cache` keeps working with no edits, and an optional onboarding pull request per repository writes the line with lanes and removes cache steps you no longer need.

How do you tell an agent’s pull request from a person’s?

By who opened it. The `runs-on` line sends pull requests opened by bot accounts to the agent lane, and a pool can also name agent branches or a list of agent accounts. The cache follows the same rule: an agent’s pull request writes only its own overlay.

Can a pull request poison the cache for everyone?

No. Only protected-branch CI and prebuilds write shared entries, and only from jobs that finish cleanly. Pull requests and agents write an overlay nobody else reads, forks write nothing, and release builds read dependencies only. Every entry records who wrote it and is signed, so a bad one is purged by writer in one command.

What happens when the agent lane runs out of budget?

Its jobs are held, never failed: they stay queued in GitHub, marked “Held: agent budget”, while people’s lanes keep running. Agents read the lane’s remaining budget and slow their pushes before it runs out, and you can raise the budget from the Runners overview with a plan.

Can I run GPU jobs or Android emulators?

Yes. Jobs that need whole GPUs or nested virtualization, such as Android emulators and VM tests, run in a full VM per job instead of a microVM. GPU runners run on your own GPU servers.

## Change one line.  
Keep your queue moving.

[Connect GitHub](https://frazer.ai/start?product=runners) [Read the runner docs](https://frazer.ai/docs/runners/github)
