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:

Move a job to Zerun

  1. 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-2cpu and zerun-4cpu.

  2. Check your workflows

    Run zerun check on your repo. It lists the jobs that can move and prints the one-line change for each. See Check a workflow.

  3. 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.

  4. Change the label on a branch and push

    - runs-on: ubuntu-latest+ runs-on: zerun-4cpu

    Move test and build jobs first. Leave jobs that deploy or publish until the others pass.

  5. 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>

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

Supported in the beta, and not
AreaSupportedNot in the beta
Runner OSUbuntu 24.04 on x64, from the Zerun imageWindows, macOS, ARM
Size2 vCPU with 8 GiB, 4 vCPU with 16 GiBGPUs, more than 4 vCPU
ReposPrivate repos on personal accountsPublic repos, organization repos
SoftwareThe 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
Containerscontainer: jobs and services:. Docker runs inside the job's VM.Nested virtualization, KVM
GitHub servicesactions/cache, artifacts, OIDC tokens, job summariesFixed 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

Limits

Limits per account
LimitValueWhat happens at the limit
Job timeout60 minutes. You can raise it to 180 minutes.The job ends.
Jobs at once4More jobs wait in GitHub's queue until one finishes.
Monthly cap$20 until you change itNew jobs fail within about 15 seconds with a message. Running jobs finish.
CreditWhat you boughtNew jobs fail within about 15 seconds with a message. Running jobs finish.

When something goes wrong

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.

Ways to stop using Zerun
You do thisLater runsQueued and running jobs
Change runs-on backRun on GitHub-hosted runnersZerun runs them until the queue is empty
Pause in the dashboardFail at the start, without a charge, with a message to switch the label or resumeRunning jobs finish. Queued jobs fail with the same message, so none hang.
Remove a repo from the AppWait in GitHub's queue until GitHub times them outRunning jobs finish

To leave Zerun for good, do these in order:

  1. Change runs-on back in every workflow that uses a Zerun label. The dashboard lists them.
  2. Wait for queued Zerun jobs to finish.
  3. Remove your repos from the App. That deletes their Zerun runner labels.
  4. 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

Permissions the Zerun GitHub App asks for
PermissionAccessWhy
AdministrationRead and writeTo add and delete runners in the repo. GitHub offers no narrower permission for that.
ActionsReadTo read job timings, for billing checks and for the comparison with GitHub-hosted runners
MetadataReadGitHub requires it for every App
Email addressesReadTo 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.