Sandal vs GitHub-hosted runners
GitHub-hosted runners are the default and they work. They are also shared VMs on network storage, billed by the minute rounded up, with no macOS parity and a 10 GB cache cap. Sandal is the same workflow on bare metal we own: change one runs-on label, keep every action and secret, pay by the second.
- $ / min · Linux 2 vCPU
- 0.008GitHub-hosted0.003Sandal
- $ / min · macOS
- 0.080GitHub-hosted0.060Sandal
- A 71-second job bills
- 2 minGitHub-hosted71 sSandal
- Cache cap
- 10 GBGitHub-hostedNoneSandal
Two good answers. Here is which one is yours.
- Your CI spend is small enough that minutes are noise and nobody waits on the queue.
- You have no self-hosted anything today and want zero moving parts.
- Jobs depend on GitHub-hosted-only paths such as the hosted toolcache.
- Builds are slow enough that people wait, and a 2–3× speedup is worth one label change.
- Minute rounding across thousands of jobs a month is real money.
- You want single-tenant machines that are destroyed after every job, with a cache that survives.
Many teams run both. runs-on is per job and a sandbox is per task; nothing here is all or nothing.
What each one actually ships.
Documented capability as of August 2026. Where the honest answer is a qualifier rather than yes or no, the qualifier is printed. Scroll sideways on a small screen.
| Area | GitHub-hosted runners | Sandal | Why it matters |
|---|---|---|---|
| Runtime | |||
| Hardware | A hyperthread on a shared instance with network block storage. | Dedicated cores on 4.5 GHz EPYC with local NVMe. | Real cores and local disk are where the 2–3× speedup lives. |
| Cache | actions/cache with a 10 GB cap per repository. | Sticky disks restored just in time, no cap, committed as a delta at teardown. | A node_modules restore in 3.1 s instead of 47 s. |
| Isolation | |||
| Tenancy | Fresh VM per job on shared hosts. | Single-tenant microVM per job, destroyed on exit. | A fork PR never touches your release job. |
| Pricing | |||
| Billing | Per minute, rounded up. | Per second; queue time is free. | A 71-second job billed as two minutes, thousands of times a month. |
| Surfaces | |||
| Operating systems | Linux, Windows, macOS. | Linux, Windows, macOS and native ARM on one meter. | One bill, one label scheme. |
| Developer experience | |||
| Migration | , | Change runs-on; every action, cache, secret and reusable workflow keeps working. | Migration cost is one line. |
Capabilities change and rates change. If something here is out of date, tell us and we will fix it the same week.
Same shape. Two meters.
Published rates, August 2026. GitHub bills by the minute rounded up; Sandal bills by the second with queue time free. macOS: GitHub $0.080 (M1, 3 cores) and $0.160 (M2 Pro, 6 cores) per minute; Sandal $0.060 per minute on Apple silicon.
- GitHub-hosted runnersLinux · 2 vCPU
- 0.008$ / minute
- SandalLinux · 2 vCPU · paused = $0
- 0.003$ / minute
Five real job lengths on the published 2 vCPU Linux rates. A 71-second job bills as two minutes on a per-minute meter; times thousands of jobs a month, that is the difference.
One label changes.
Sandal registers as a self-hosted runner, so GitHub keeps orchestrating. Every action, cache, secret and reusable workflow keeps working.
- 01≈ 2 min
Install the app
Grant Actions and workflow read on the repos you want to move. Sandal registers as a self-hosted runner; GitHub keeps orchestrating.
- 02≈ 5 min
Swap the label
npx sandal migrate rewrites runs-on, resolves matrices, and opens a PR. Review the diff before merging.
- 03≈ 1 week
Watch a week of jobs
If the first week is not faster and cheaper, change the label back.
What we would rather you read here than find later.
A comparison page where the vendor wins every row is a brochure. These are real, and we would rather you land on the right tool than land on us and leave in a month.
- 01
Nothing to set up.
GitHub-hosted runners need no app, no label, no vendor. For a small repo with short jobs the difference is minutes a month.
Questions teams ask before moving off GitHub-hosted runners.
Yes. Sandal registers as a self-hosted runner, so GitHub keeps orchestrating the workflow. The only change is the runs-on label.
The rest of the field in ci runners.
Run the same job twice.
Point one workload at Sandal and one at GitHub-hosted runners. The numbers on this page are ours; the ones that matter are yours.