An alternative to Actions Runner Controller — without running Kubernetes.
You adopted ARC for control and cost, and it delivers both. But you also took on a Kubernetes cluster, a controller, an autoscaler, and a runner-image pipeline to keep healthy. RunsOn keeps the part you wanted — self-hosted, ephemeral runners in your own AWS account — and drops the cluster: one CloudFormation stack, any EC2 instance per job.
What ARC asks you to operate.
None of this is a flaw in ARC — it's the cost of building runners on top of Kubernetes. If your team isn't already running a cluster for its own sake, that's a lot of moving parts to own just to get CI.
A cluster to own
EKS or self-managed Kubernetes, upgrades, node pools, and the on-call that comes with a production cluster — before a single job runs.
A controller + autoscaler to tune
The controller and runner scale sets, plus node autoscaling, all have knobs. Getting burst behaviour and scale-down right is ongoing work.
Runner images to maintain
ARC runs container images you build and patch. Matching the tooling in GitHub's official runners is the part most teams underestimate.
Idle capacity that still bills
Node pools sized for peak cost money when the queue is empty. Tuning scale-to-zero on Kubernetes is possible, but it's never free.
Windows & GPU are extra projects
Both are doable on ARC, but each means more node groups, more images, and more cluster surface area to keep working.
You're the integration layer
When the runner API, the listener, or a node misbehaves, debugging sits with your platform team. There's no managed path underneath.
The core difference: what you operate.
Both ARC and RunsOn are self-hosted — your code, secrets, and artifacts stay in your own account either way. The difference isn't where the work runs. It's the stack you have to keep alive to make runners appear.
the stack you operate
Maximum control — at the price of running a production Kubernetes cluster whose only job may be CI.
what comes up, managed
No cluster. Managed AWS services launch a fresh instance per job and tear it down after. The control plane itself costs only a few dollars a month.
What changes when you drop the cluster.
Three things you stop doing the day you move off ARC.
Managed AWS services, not a cluster
One CloudFormation stack provisions the scheduler, queues, cache, and metrics. No nodes, no pods, no controller to patch. Nothing to be on-call for at 2am.
Official-image AMIs, one-line migration
RunsOn ships AMIs ported from GitHub's own Packer templates, so your existing actions, caches, and secrets keep working. Migration is a label change.
runs-on: runner=2cpu-linux-x64
runs-on: runner=16cpu-linux-arm64
runs-on: family=g6e.xlarge
runs-on: image=windows25-full-x64 Any instance per job, scale to zero
Each job gets its own ephemeral EC2 — x64, arm64, Windows, or GPU, from 1 to 896 vCPUs. No node pools sized for peak, no idle capacity on the bill.
Head to head, by dimension.
Both are self-hosted and keep jobs in your account. Here's where the operational model differs — framed structurally, not by cherry-picked benchmark numbers.
| dimension | Actions Runner Controller | RunsOn |
|---|---|---|
| Prerequisite | A running Kubernetes cluster (EKS or self-managed) plus Helm. | One CloudFormation stack and a private GitHub App. No cluster. |
| Scaling | Runner scale sets on nodes you size; node autoscaler tuned by you. | One ephemeral EC2 per job, launched on demand, scales to zero. |
| Runner images | Container images you build, patch, and keep close to GitHub's toolset. | AMIs ported from GitHub's official Packer templates, kept updated for you. |
| Windows & GPU | Possible, but each adds node groups, images, and cluster surface area. | Pick the instance and image in the label — any EC2 shape, 1–896 vCPUs. |
| Idle cost | Node pools sized for peak keep billing when the queue is empty. | No persistent runners; control plane is a few dollars a month. |
| Who operates itrecommended | Your platform team owns the cluster, controller, scaling, and on-call. | Managed AWS services underneath; you own labels and an annual upgrade. |
| Setup time | Cluster bring-up, Helm install, scale-set and image configuration. | About 10 minutes to a first job, with little AWS knowledge required. |
Where each option fits.
ARC and RunsOn aren't the only ways off GitHub-hosted runners. The honest one-liner for each, so you can see the whole field before committing.
| option | where it wins | the tradeoff |
|---|---|---|
| GitHub-hostedruns on GitHub | Zero setup, native UX, fine for small standard jobs. | Limited instance choice and higher per-minute pricing at scale. |
| Actions Runner Controllerruns in your cluster | Deep control for teams already standardized on Kubernetes. | You own the cluster, autoscaler, images, and runner operations. |
| Self-managed Terraformruns in your account | Modules like the Philips runner give autoscaling without Kubernetes. | Still your code to operate, and not image-compatible without custom AMIs. |
| RunsOnrecommendedruns in your account | Ephemeral EC2 in your AWS account, any shape, no cluster, official-parity images. | AWS-only, and you deploy a small CloudFormation stack first. |
| AWS CodeBuildruns in your account | Native AWS service and AWS procurement path. | Different runner model, weaker Actions ergonomics, less flexible instance selection. |
Leaving ARC doesn't mean leaving self-hosted.
The reason you chose ARC in the first place — code and secrets staying inside your own boundary — is exactly what RunsOn preserves. This is a change of operational model, not a handoff to someone else's cloud.
what stays inside
Same boundary as ARC. Your IAM, your VPC, your network — just without the cluster underneath it.
what would leave your account
The trade ARC users specifically avoided. RunsOn doesn't ask you to make it.
Moving from ARC, step by step.
You can run RunsOn alongside ARC and cut workflows over gradually — there's no big-bang switch.
Deploy the stack
Launch one CloudFormation stack and install a private GitHub App for your org. About 10 minutes, little AWS knowledge required.
Switch the labels
Change runs-on: on a pilot workflow to a RunsOn
label. Official-parity AMIs mean actions, caches, and secrets keep working
unchanged.
Decommission the cluster
Once everything's cut over, tear down the controller, scale sets, node pools, and the runner-image pipeline you no longer maintain.
When ARC is still the right call.
RunsOn isn't the answer for everyone. Three cases where staying on ARC (or another tool) makes more sense.
You're not on AWS
RunsOn is AWS-only. If your infrastructure lives on GCP or Azure, ARC runs anywhere Kubernetes does — keep it, or pick a cloud-native option.
Kubernetes is your platform
If you already run a cluster and want CI co-located with other workloads, sharing nodes and tooling, ARC fits that model naturally.
You need in-cluster semantics
Some workflows depend on running inside the cluster — service networking, sidecars, or pod-level isolation. RunsOn runs jobs on EC2 instances instead.
Questions teams ask when leaving ARC.
The short version of the comparison above.
Drop-in replacement?
Effectively yes. Deploy the stack and a GitHub App, then change the
runs-on: label. Official-parity AMIs keep actions,
caches, and secrets working.
Do I need Kubernetes?
No. RunsOn uses managed AWS services and ephemeral EC2 — no nodes, pods, or scale sets. That's the whole point of the move.
Still my own account?
Yes. Control plane, runners, logs, artifacts, secrets, and cache all stay in your AWS account, exactly like ARC. GitHub only sends the job request.
How does autoscaling work?
One ephemeral EC2 per job, launched on demand and terminated after, scaling to zero. No node pool to size; bursts launch that many instances.
Windows & GPU?
Supported via the label — x64, arm64, Windows, and GPU, any EC2 shape up to 896 vCPUs. No extra node groups to stand up.
How long to migrate?
~10 minutes to install, then cut workflows over at your own pace and decommission the cluster when you're done. Run both side by side meanwhile.
Self-hosted runners, without the cluster.
One CloudFormation stack, a private GitHub App, ~10 minutes. Keep the control and the cost savings you went to ARC for — drop the Kubernetes you didn't.