Docs
How to move a job to Zerun, what the beta supports, and how to move back to GitHub-hosted runners.
Before you start
You need all of these:
- A personal GitHub account. Organization accounts are not in the beta.
- A private repo. Zerun refuses public repos.
- Jobs that run on Linux x64.
- An invite to the beta. Ask for one at beta@zerun.example.
Move a job to Zerun
Install the Zerun GitHub App
Sign in to the Zerun dashboard with GitHub and install the App on the private repos you choose. Zerun adds two runner labels to each repo,
zerun-2cpuandzerun-4cpu.Check your workflows
Run
zerun checkon your repo. It lists the jobs that can move and prints the one-line change for each. See Check a workflow.Buy credit and set a cap
Buy credit in the dashboard before your first job, in packs of $10, $25 or $50. Without credit, new jobs fail within about 15 seconds with a message. The monthly cap is $20 until you change it. See pricing.
Change the label on a branch and push
- runs-on: ubuntu-latest+ runs-on: zerun-4cpuMove test and build jobs first. Leave jobs that deploy or publish until the others pass.
Watch the job
GitHub runs the job on Zerun and shows the checks as usual. The dashboard lists each job with its queue time, duration, vCPU-seconds, charge and outcome.
Check a workflow
zerun check reads workflow files and tells you which jobs can run on Zerun. It reads files on your machine and sends nothing anywhere. Beta users get the zerun command with their invite.
zerun check [--size 2|4] [--json] <workflow files or directories>- Give it workflow files or directories. For a repo root, it reads
.github/workflows. --sizepicks the label in the suggested change. It is2unless you give4.--jsonprints the same report as JSON.- It exits with 0 when it read every file, 1 when a file could not be read or parsed, and 2 for a usage error. A job that cannot move is a normal result, not an error.
For each job, it gives every runs-on value a verdict: eligible, already on Zerun, not eligible with the reason, check the called workflow, or unknown. It warns about tools that GitHub preinstalls and Zerun does not, about container jobs, and about jobs that deploy or publish. Here is a report for a workflow with two jobs:
$ zerun check --size 4 .github/workflows/test.yml
.github/workflows/test.yml
test (line 4)
ubuntu-latest: eligible.
warning .github/workflows/test.yml:8: The job calls npm, which GitHub-hosted runners preinstall and the Zerun image does not. Add actions/setup-node before this step.
change .github/workflows/test.yml:5
- runs-on: ubuntu-latest
+ runs-on: zerun-4cpu
release (line 10)
macos-latest: not eligible. macOS runners are not in the beta.
1 of 2 jobs have a runs-on change.
Known differences for every job on Zerun:
Jobs reach the internet from AWS Sydney (ap-southeast-2) addresses, not from GitHub's.
Disk and CPU models differ from GitHub-hosted runners, so durations can differ.What the beta supports
| Area | Supported | Not in the beta |
|---|---|---|
| Runner OS | Ubuntu 24.04 on x64, from the Zerun image | Windows, macOS, ARM |
| Size | 2 vCPU with 8 GiB, 4 vCPU with 16 GiB | GPUs, more than 4 vCPU |
| Repos | Private repos on personal accounts | Public repos, organization repos |
| Software | The runner, git, Docker Engine with buildx and compose, build-essential, curl, jq and Python 3. setup-* actions download other toolchains. | The full set of tools GitHub preinstalls |
| Containers | container: jobs and services:. Docker runs inside the job's VM. | Nested virtualization, KVM |
| GitHub services | actions/cache, artifacts, OIDC tokens, job summaries | Fixed outbound IP addresses |
Zerun keeps no cache of its own between jobs. actions/cache works as it does on GitHub-hosted runners, under GitHub's own rules.
Known differences from ubuntu-latest
- The image has fewer tools.
zerun checknames the tools a job calls that the image lacks, and thesetup-*action that installs each one when there is one. - Jobs reach the internet from AWS addresses in Asia Pacific (Sydney), ap-southeast-2, not from GitHub's.
- Docker Hub limits anonymous pulls per IP address. If pulls from Docker Hub fail, log in to Docker Hub in the job.
- Disk and CPU models differ from GitHub-hosted runners, so durations can differ.
Limits
| Limit | Value | What happens at the limit |
|---|---|---|
| Job timeout | 60 minutes. You can raise it to 180 minutes. | The job ends. |
| Jobs at once | 4 | More jobs wait in GitHub's queue until one finishes. |
| Monthly cap | $20 until you change it | New jobs fail within about 15 seconds with a message. Running jobs finish. |
| Credit | What you bought | New jobs fail within about 15 seconds with a message. Running jobs finish. |
When something goes wrong
- A job that fails because of Zerun is not charged. The dashboard marks it as an infrastructure failure, and Zerun emails you a link to the job so you can re-run it with GitHub's re-run button. Zerun does not re-run jobs for you.
- If AWS has no capacity, jobs wait in GitHub's queue while Zerun keeps trying. After 10 minutes, Zerun emails you once with the steps to move the jobs back to GitHub-hosted runners.
- If Zerun itself is down, running jobs carry on, because they talk to GitHub directly. New jobs wait in GitHub's queue.
Turn Zerun off
GitHub fixes a run's runs-on label when the run is created. A change to the workflow therefore affects only later runs. Jobs that are already queued still need a Zerun runner.
| You do this | Later runs | Queued and running jobs |
|---|---|---|
Change runs-on back | Run on GitHub-hosted runners | Zerun runs them until the queue is empty |
| Pause in the dashboard | Fail at the start, without a charge, with a message to switch the label or resume | Running jobs finish. Queued jobs fail with the same message, so none hang. |
| Remove a repo from the App | Wait in GitHub's queue until GitHub times them out | Running jobs finish |
To leave Zerun for good, do these in order:
- Change
runs-onback in every workflow that uses a Zerun label. The dashboard lists them. - Wait for queued Zerun jobs to finish.
- Remove your repos from the App. That deletes their Zerun runner labels.
- Uninstall the App.
If you uninstall the App first, GitHub revokes its access before Zerun hears about it. The labels then stay registered with no runner behind them, and jobs that target them wait in GitHub's queue. For unused credit, see the refund policy.
What Zerun can access
| Permission | Access | Why |
|---|---|---|
| Administration | Read and write | To add and delete runners in the repo. GitHub offers no narrower permission for that. |
| Actions | Read | To read job timings, for billing checks and for the comparison with GitHub-hosted runners |
| Metadata | Read | GitHub requires it for every App |
| Email addresses | Read | To send balance and cap alerts |
The App does not ask for Contents, Actions write, Checks or Pull requests, so it cannot read your code or re-run your jobs. Step logs and secrets go between the runner and GitHub, and Zerun does not receive them.
Zerun keeps a record of each job, including its repo, workflow, job name, commit SHA, timings, charge and result. It also keeps statistics such as the tree hash of the job's checkout. It never keeps your code, step logs or secrets. The privacy policy lists everything Zerun stores.