quickstart →

An alternative to Actions Runner Controller, without Kubernetes.

You adopted ARC for control and cost. It came with a Kubernetes cluster, a controller, an autoscaler and a runner-image pipeline to keep healthy. RunsOn keeps the ephemeral runners in your own AWS account and replaces the rest with one CloudFormation stack. Every job gets a fresh EC2 instance on Spot, and nothing runs while the queue is empty.

Then a flat license from €300 / $350 a year, less than one day of a platform engineer's time. Run it next to ARC and move one workflow at a time.

“We were able to both reduce cost and decrease duration of our jobs, running hundreds/thousands of jobs on very large machines daily. This replaced our previous usage of the k8s-based github actions-runner-controller.”
Christian Theilemann, Software Engineer, Aptos Labs
  • ~10 minutesone CloudFormation stack, no cluster or Helm
  • 1 EC2 per jobno runner pools to size, scales to zero
  • 6–13× cheaperthan GitHub-hosted, Spot by default
  • x64 · arm64 · GPUand Windows, picked by label

What ARC asks you to operate, handled.

ARC builds runners on Kubernetes, so running ARC means running all of this. With RunsOn each line is taken care of by the stack.

handled

To do: keep ARC runningwith RunsOn: 6 of 6 handled

  • Run and upgrade the cluster

    EKS or self-managed Kubernetes, with its upgrades, node pools and on-call, before a single job runs.

    RunsOn No cluster. One CloudFormation stack brings up managed AWS services.

  • Tune the controller and the autoscaler

    The controller, the runner scale sets and node autoscaling each have their own settings. Getting bursts and scale-down right is ongoing work.

    RunsOn One EC2 instance per job, launched when the job queues and terminated after.

  • Rebuild the runner images

    ARC runs container images you build and patch. Keeping them close to the tooling in GitHub's own runners is the part most teams underestimate.

    RunsOn AMIs ported from GitHub's own Packer templates, kept updated for you.

  • Pay for the idle node pools

    Node pools sized for peak cost money when the queue is empty, and scale-to-zero on Kubernetes is one more thing to tune.

    RunsOn No persistent runners. The control plane costs a few dollars a month.

  • Add node groups for Windows and GPU

    Both work on ARC, and each one adds node groups, images and cluster surface to keep working.

    RunsOn The label picks the instance and the image: any EC2 type, 1 to 896 vCPUs.

  • Debug the listener, the runner API, the nodes

    When the listener, the runner API or a node misbehaves, your platform team debugs it. Nobody maintains the layer underneath for you.

    RunsOn Managed AWS services underneath. You own the labels and the stack upgrades.

Same account, a smaller stack to operate.

ARC and RunsOn are both self-hosted: your code and secrets stay in your own account either way. What differs is the stack you keep alive so that runners appear.

actions runner controller

the stack you operate

kubernetes cluster helm controller runner scale sets node autoscaler custom runner images cluster upgrades
↻ you own scaling, images and on-call

Full control, and a production Kubernetes cluster whose only job may be CI.

no cluster runs-on: your aws account

what comes up, managed

1 cloudformation stack scheduler (fargate) ephemeral ec2 per job official-parity amis s3 cache scale to zero
← github only sends in the job request

No cluster. Managed AWS services launch a fresh instance per job and terminate it after. The control plane costs a few dollars a month.

What changes when you drop the cluster.

Three things you stop doing the day you move off ARC.

01 no kubernetes

Managed AWS services, not a cluster

One CloudFormation stack provisions the scheduler, queues, cache and metrics on managed AWS services. There are no nodes or pods to patch.

02 image parity

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.

.github/workflows/ci.ymlyaml
runs-on: runner=2cpu-linux-x64
runs-on: runner=16cpu-linux-arm64
runs-on: family=g6e.xlarge
runs-on: image=windows25-full-x64
03 per-job ec2

Any instance per job, scale to zero

Each job gets its own EC2 instance: x64, arm64, Windows or GPU, from 1 to 896 vCPUs. No node pool is sized for peak, and nothing idle is on the bill.

licensefrom €300 / $350 a year
computebilled by AWS, direct
idlescales to zero

Where each option fits.

The other ways off GitHub-hosted runners, with what each one asks of you.

option where it wins the tradeoff
GitHub-hostedruns on GitHub No setup, and fine for small standard jobs. Few instance sizes and the highest per-minute price.
Actions Runner Controllerruns in your cluster Deep control for teams already standardized on Kubernetes. You operate the cluster, the autoscaler and the runner images.
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 One EC2 instance per job in your AWS account, any type, with images ported from GitHub's. AWS only, and you deploy a CloudFormation stack first.
AWS CodeBuildruns in your account Native AWS service and AWS procurement path. Its own runner model and compute types, with a narrower choice of instances.
your account / cluster github infrastructure Full GitHub Actions runner comparison →

You leave ARC and stay self-hosted.

You chose ARC so that code and secrets stay inside your own boundary. With RunsOn they still do: the runners are EC2 instances in your VPC, and nothing moves to a vendor's cloud.

nothing leaves runs-on: your aws account

what stays inside

control plane ephemeral runners secrets s3 cache
← github only sends in the job request

Same boundary as ARC: your IAM, your VPC, your network. The cluster underneath is gone.

third-party hosted runners

what would leave your account

your source code build secrets caches
→ checkout runs on the vendor's machines

The trade you avoided by choosing ARC. RunsOn doesn't ask for it either.

Moving from ARC, one workflow at a time.

RunsOn runs next to ARC. The cluster stays up until the last workflow has moved.

01

Deploy the stack

Launch one CloudFormation stack and install a private GitHub App for your org. It takes about 10 minutes and little AWS knowledge.

~10 min · one stack
02

Switch the labels

Change runs-on: on a pilot workflow to a RunsOn label. The AMIs are ported from GitHub's images, so actions, caches and secrets keep working.

per-workflow · reversible
03
done

Decommission the cluster

Once every workflow has moved, tear down the controller, the scale sets, the node pools and the runner-image pipeline.

stop operating k8s

When ARC is still the right call.

×

You're not on AWS

RunsOn runs only on AWS. ARC runs anywhere Kubernetes does, so on GCP or Azure it stays the better choice.

×

Kubernetes is your platform

You already run a cluster and want CI next to your other workloads, on the same nodes and tooling. ARC is built for that.

×

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.

Questions teams ask when leaving ARC.

Drop-in replacement?

Close to it. Deploy the stack and a GitHub App, then change the runs-on: label. The AMIs are ported from GitHub's images, so actions, caches and secrets keep working.

Do I need Kubernetes?

No. RunsOn uses managed AWS services and one EC2 instance per job. There are no nodes, pods or scale sets.

Still my own account?

Yes. The control plane, runners, secrets and cache all stay in your AWS account, as with ARC. GitHub only sends the job request.

How does autoscaling work?

One EC2 instance per job, launched when the job queues and terminated after. There is no node pool to size: a burst of 100 jobs launches 100 instances.

Windows and GPU?

Both are picked in the label: x64, arm64, Windows and GPU, on any EC2 type up to 896 vCPUs, with no node groups to add.

How long to migrate?

About 10 minutes to install. Then you move workflows at your own pace, with ARC running alongside, and decommission the cluster when the last one has moved.

~10 min setup

Self-hosted runners, without the cluster.

One CloudFormation stack, a private GitHub App, about 10 minutes. You keep the control and the savings you went to ARC for, and the Kubernetes goes away. The 15-day trial runs the real product in your account, next to ARC.