CI without managing runners.
A single-tenant microVM for every job, on bare metal we own. One line changes in your workflow file. Billed by the second, with queue time free.
That is the whole migration. Same steps, same actions, same secrets. Only the executor underneath changes.
A clean machine, every job.
Self-hosted runners rot: state from the last job leaks into the next, and a malicious fork PR gets a machine somebody else will use later. Sandal never reuses a machine.
One job, one microVM.
Firecracker boots a single-tenant VM when the job is queued and destroys it the moment the job exits. Every job gets its own guest kernel over KVM, run sudo, Docker, Kubernetes and kernel modules directly, no Docker-in-Docker, no user-namespace hacks.
Boot <1s · teardown 180ms · runner token lifetime: one job.
Ephemeral machines, persistent cache.
A sticky disk is a named volume attached to a label. It survives across jobs even though the machine does not, mounted by name, restored lazily on first read, and committed as a delta at teardown rather than re-uploaded.
| 3.1s | node_modules restore, down from 47s with actions/cache |
| 2.4s | until a 6.2 GB pnpm store is usable after mount |
| 40–90 MB | typical delta committed at teardown, not a full re-upload |
| $0.15 | per GB-month · first 10 GB per org free · idle disks released after 30 days |
Apple silicon we actually own.
Apple-silicon Mac minis in our racks, one job at a time. Every job gets a fresh VM created with Virtualization.framework from a golden image, deleted when the job ends. Keychains, provisioning profiles and derived data never cross between builds.
Simulators and Xcode builds| Host | Mac mini, Apple silicon, dedicated · one job per host |
| Xcode | 16.4 · 16.2 · 15.4, selectable with xcode-select |
| Runtimes | iOS 18.4 · iOS 17.5 · watchOS 11 |
| Claim | 12s median from a warm pool |
| Rate | $0.01 / min |
Linux, Arm and macOS in one file.
Runner size and OS are part of the label, so machine selection lives in the workflow file and travels with the pull request that needs it. Matrix x86, aarch64 and Apple silicon legs in the same job and the same account.
Three steps to faster CI.
No runner VMs to provision, no agent to install on a box you own, no autoscaler to babysit. Median time from install to first green job on Sandal hardware: 4 minutes.
- 01
Install the GitHub App
Grant it Actions and workflow read on the repositories you want to move. It never reads your source outside of a job it is running.
- 02
Swap the label
Change runs-on: ubuntu-latest to runs-on: sandal-ubuntu-24.04. The migration wizard rewrites the labels for you and opens a pull request.
- 03
Push
The next queued job claims a fresh microVM on our metal instead of a shared GitHub VM. Logs, annotations, secrets, OIDC, artifacts and re-runs work as before.
Faster because
the hardware is faster.
One vCPU is one physical core on a 4.5 GHz EPYC, not a hyperthread on a five-year-old cloud instance. Local NVMe instead of network block storage. Medians from workflows that run every six hours on public repositories.
Workload Test Comparison
Pick it in the workflow file.
RAM scales with vCPU at 2 GB per core on Linux and 4 GB per core on Windows. Disk is 150 GB on every shape. If a label does not exist, the job fails fast at claim time with the list of valid labels, rather than queueing forever.
Routes the job to our fleet.
The prefix moves the job off GitHub’s pool and onto ours. Everything after it describes the machine.
Image family and version.
ubuntu-24.04, windows-2025, macos-m4. Add -arm to any Ubuntu label to move it to aarch64.
vCPU count.
2, 4, 8, 16, 32, 64. Omit it for the 2 vCPU / 4 GB default. Machine selection travels with the pull request that needs it.
No CI tax.
A runner is just a sandbox billed by the minute, priced at the same $0.036/VM-hour machine, so a CI minute is a fraction of a cent. GitHub’s published per-minute rate sits alongside ours.
Billed per second, never rounded to the minute, a 71-second job bills 71 seconds. Queue time is free; a cancelled job bills only the seconds that ran.
Run every job at once.
There is no per-plan concurrency licence to buy. A 400-job matrix starts 400 microVMs; the job start rate is 60/s on every plan and the ceilings are published up front.
1.9s median, 4.2s P99.
Measured over 30 days on our own monorepo, 1.2M jobs, through a 500-job spike. GitHub’s P50 on the same runs was 11.4s. Warm pools keep it flat as the burst grows.
One balance. Every machine you run.
Runners draw from the same credit pool as your sandboxes, simulators and Xcode builds, billed by the second at one published rate card.
Starter
For a solo build or a first agent in production.
$20 of usage credits
≈ 550 VM-hours or 33,000 CI minutes
- 20 concurrent machines
- Committed in-plan rates on every product
- Linux & Windows, sandboxes, VMs, runners
- Per-second billing, paused is free
- Full API, SDKs, CLI & MCP server
- Unlimited seats
- Community support
Team
Apple silicon unlocked, and a balance that rolls over.
$100 of usage credits
≈ 2,700 VM-hours or 10,000 Mac build minutes
- 100 concurrent machines
- Everything in Starter, plus:
- macOS, iOS/Android simulators & Xcode builds
- Unused credits roll over one month
- Usage exports & per-second line items
- Email support
Business
Higher ceilings for a team leaning on the fleet daily.
$250 of usage credits
≈ 6,900 VM-hours or 25,000 Mac build minutes
- 300 concurrent machines
- Everything in Team, plus:
- Raised concurrency & start rate
- Priority support & shared Slack channel
- Single sign-on (SAML / OIDC)
- Volume credit rate
Enterprise
Dedicated capacity, your compliance surface, one invoice.
Committed volume rate
Committed volume rate, negotiated per account
- Reserved bare-metal capacity
- BYOC or self-host the control plane
- SSO & SCIM, audit logs, data residency
- Annual invoicing, MSA, DPA
- Support SLA & solutions engineering
- Custom regions on request
Every plan spends its credit pool first, then usage keeps flowing and bills per second at your committed in-plan rate, no hard stop mid-run, no forced upgrade. Without a plan you pay the on-demand rate instead. Prices are illustrative pending final list pricing; the per-second billing model is final.
The runner rate card.
Linux
Windows
macOS · Apple silicon
Linux runners are the VM ladder priced per minute; Windows is 2x. macOS runners are dedicated Apple-silicon Mac minis. On-demand is 1.5× the in-plan rate. All usage bills by the second; paused machines are not billed.
Give your AI agents somewhere to run today.
Your agents get their own machines across Linux, macOS, Windows, iOS and Xcode in milliseconds, and you stop paying for idle.
