runner supply for GitHub Actions

CI on your
own iron.

ushr schedules GitHub Actions jobs onto hardware you already own: ephemeral VMs, just-in-time runner registration, one priority queue across every org. Your workflows don't change. Your bill does.

Join the waitlisthosted control plane · early access
  • runner lifetime: exactly one job, then the VM is destroyed
  • your keys: never leave your machines
  • pipeline migration: none; it's still GitHub Actions
dispatch ledger · live2 orgs · 3 runners
14:02:07build-ios #8841dispatchedushr-m2-01
14:02:09unit-tests #8842dispatchedushr-m2-02
14:02:31build-ios #8841runningushr-m2-01
14:03:04lint #8843queuedqueue: labs
14:05:56unit-tests #8842done4 min · $0.32
14:05:58lint #8843dispatchedushr-m2-02
14:09:12build-ios #8841done7 min · $0.56
saved this hour: $0.88 · on GitHub-hosted this would still be queued

One fleet. Every org.

GitHub scopes self-hosted runners to a single org. Share hardware across orgs the traditional way and you're installing a separate runner service per org on every machine, partitioning the fleet by hand, and watching one org's Macs sit idle while another org queues.

ushr unpins the hardware. One agent serves all your orgs; every job gets a fresh runner minted just-in-time into whichever org is next by priority and age. The busiest queue gets the iron.

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 · runners minted into the org that needs them
acme-labse2e #311dispatched → mac-01
acme-labse2e #312dispatched → mac-02
acme-engnightly #88done → mac-03

Keyless by architecture

The control plane is a scheduling brain, nothing more. Your agent dials out; queue metadata goes up, dispatch decisions come down. The GitHub App key stays on your machine, mints just-in-time runner tokens locally, and your runners talk to GitHub directly.

There is no credential to breach on our side, because we never hold one. That's not a policy, it's the wire protocol.

ushr.iocontrol plane

scheduler · dispatch ledger · analytics

metadata ↑
dispatch ↓
your ironopen-source agent

polls GitHub · mints JIT tokens · provisions VMs

🔒 App key never leaves this box

runners register just-in-time
github.comunchanged

How it works

  1. 1

    ushr setup

    One command creates your GitHub App via the manifest flow. The private key is written to your machine, not ours.

  2. 2

    Run the agent on your iron

    Mac minis, Linux boxes, the tower under the desk. Tart, Lume or Docker isolation; each runner registers just-in-time and serves one job.

  3. 3

    Label your jobs

    runs-on: [self-hosted, macos] and you're routed. ushr dispatches by label, priority and age across every org you run, from one queue.

driverstartlumedockerk8s: plannedlabelsmacoslinuxarm64x64

The meter runs backwards

GitHub-hosted macOS runners bill at $0.08 a minute. A Mac mini on your shelf bills at zero. Drag the slider to your team's monthly runner-minutes and watch the invoice unhappen.

runner-minutes / month12,000
$960
saved / month
$11,520
/ year
vs GitHub-hosted macOS
at $0.08/min

the receipts

$ ushr cost
ushr cost: last 30 days (rate $0.080/runner-min)

        ORG   JOBS   RUNNER-MIN      SAVED
   acme-eng    412         9840    $787.20
  acme-labs     96         2310    $184.80
      TOTAL    508        12150    $972.00

real subcommand, ships in the open-source CLI

The control plane, hosted

ushr.io schedules across your fleet while your hardware does the work. Keys, code and secrets never cross the wire. Early access is rolling out now.

© 2026 ushrusher, without the e