Runner supply for GitHub Actions

Your hardware.
Your CI.

Run GitHub Actions on your Macs and Linux machines. Share capacity across organisations. Keep your keys on your hardware.

Hosted control plane · Open-source agent

ushr / acme workspaceSample data

Your hardware, working together.

One fleet. Every org.

mac-studio-01macOS · ARM64acme-eng
mac-mini-02macOS · ARM64acme-labs
linux-01Linux · x64acme-eng
Keys stay on your machines.
  • 01 One job per runner
  • 02 Keys stay local
  • 03 Still GitHub Actions

One fleet. Every org.

Share your Macs and Linux machines across organisations. ushr assigns capacity by job priority and waiting time. Every job gets a fresh, isolated runner.

runners pinned per org · the old way
acme-engmac-01 mac-02idle all week
acme-labsmac-037 jobs queued
↓ same hardware, ushr scheduling
one queue · 3 machines · 6 VM slots
acme-labse2e #311dispatched → mac-01·vm1
acme-labse2e #312dispatched → mac-01·vm2
acme-engnightly #88done → mac-02·vm1

Your silicon, your cache

Build with your machine's cores and local storage. On Linux hosts, ushr keeps each repo's Docker build cache on the machine, ready for the next run.

where the job runs
hardware
github-hostedGitHub's runner VM
ushryour Mac or Linux machine
docker build cache
github-hostedempty each job
ushrkept per repo on Linux hosts
queue
github-hostedGitHub's hosted pool
ushryour fleet, dispatched by ushr
build times depend on your hardware

Keyless by architecture

Your GitHub App key stays on your machine. ushr.io exchanges queue metadata and dispatch decisions with your agent. Your runners connect directly to GitHub.

ushr.iocontrol plane

scheduler · dispatch ledger · analytics

metadata ↑
dispatch ↓
your ironopen-source agent

polls GitHub · mints JIT tokens · provisions VMs

[key] never leaves this box

runners register just-in-time
github.comunchanged

How it works

  1. 1

    curl get.ushr.io | sh

    Install the CLI and agent on an Apple Silicon Mac or Linux machine.

  2. 2

    ushr login

    Follow the guided setup to connect GitHub and start your agent. Your App key stays on this machine.

  3. 3

    Label your jobs

    Set runs-on: [self-hosted, macos] in your workflow. ushr routes each job to matching hardware.

$ curl -fsSL https://get.ushr.io | sh
==> Downloading ushr (darwin/arm64)
==> Installed ushr to ~/.local/bin

$ ushr login
==> Wrote default agent config: ~/.config/ushr/agent.yaml
==> tart image "runner-mac" present ✓
==> Opening https://ushr.io/cli/auth… 
==> Confirmation code: KTX-42P
==> Waiting for approval........ ✓
✓ Enrolled agent "mini-01" for org(s) acme-eng
✓ ushr-agent service running
  Target jobs with:  runs-on: [self-hosted, macOS, ARM64]

real output, not a mockup: a fresh machine to a live runner in two commands

driverstartlumedockerk8s: plannedlabelsmacoslinuxarm64x64

The meter runs backwards

Estimate the GitHub-hosted macOS charges you could avoid, less the ushr fee. Set your monthly macOS runner-minutes and hosts below.

runner-minutes / month12,000
hosts2
US$695
net / month
US$8,340
/ year
vs GitHub-hosted macOS
at US$0.062/min, less ushr Pro

GitHub-hosted macOS 3- and 4-core list price, minus ushr Pro at US$49 per month for up to 3 hosts and US$19 per extra host. Excludes your hardware and power, and GitHub's included minutes. Linux minutes cost less on GitHub.

example output

$ ushr cost
ushr cost — last 30 days (rate $0.062/runner-min)

         ORG   JOBS   RUNNER-MIN   AVOIDED
    acme-eng    412         9840   $610.08
   acme-labs     96         2310   $143.22
       TOTAL    508        12150   $753.30

Sample orgs. ushr cost ships in the CLI for self-hosted controllers. AVOIDED is runner-minutes × the GitHub-hosted macOS rate, before hardware and power. Pass --rate to use another GitHub rate.

The control plane, hosted

Free for 1 host and 1 GitHub scope (an organisation, or a repository on a personal account). Pro is US$49 per month for up to 3 hosts, plus US$19 per extra host, with unlimited scopes.