Self-hosted GitHub Actions runners, without maintaining them.
RunsOn gives you self-hosted GitHub Actions runners in your own AWS account, and keeps them running for you. Each job gets a fresh EC2 instance on Spot that is terminated when the job ends. One CloudFormation stack replaces the Kubernetes cluster, the autoscaler and the runner image pipeline.
Installs in about 10 minutes · card at checkout, nothing charged for 15 days · then from €300 / $350 a year · free for non-commercial use
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64
steps:
- uses: actions/checkout@v7 That label is the whole migration for a job. The runner images are built from GitHub's own image definitions, so your steps stay as they are. You move one workflow at a time, and the rest keep running where they are.
- ~10 minutesone CloudFormation stack and a private GitHub App
- 1 EC2 per jobterminated after the job, nothing idle
- 5–19× cheaperthan GitHub-hosted Linux, on Spot
- x64 · arm64 · GPUand Windows, picked per job
Looking to register a runner on a machine you already have? GitHub's guide covers that: Adding self-hosted runners. RunsOn is for teams that want runners on AWS without building and operating the fleet themselves.
Self-hosting usually means owning a fleet.
GitHub's runner agent is the easy part. Around it you need machines that appear when jobs queue and go away after, images that track GitHub's, caching, Spot interruptions and a cost report. With Actions Runner Controller you also run Kubernetes. RunsOn ships all of that as one stack in your account.
| the job | running it yourself | with RunsOn |
|---|---|---|
| Scaling | Size node pools or warm instances for peak, and pay for them when the queue is empty. | One EC2 instance per job, launched when the job queues and terminated when it ends. |
| Runner images | Build and patch your own images, and chase what GitHub's images add. | Linux images compatible with GitHub's Ubuntu images, rebuilt every 15 days from the upstream definitions. Platforms → |
| Spot | Write the interruption and capacity handling, or stay on on-demand. | Spot first, with automatic on-demand fallback. Spot pricing → |
| Instance choice | One pool or scale set per shape you want to offer. |
Any EC2 type per job, from the label:
family=c8a, cpu=16,
image=ubuntu24-full-arm64. Labels → |
| Caching | GitHub's cache from AWS, over the internet, or a cache service you run. | An S3 cache bucket in your account, and Docker layer caching. |
| Cost | Tag and attribute instances yourself. | Cost reports by email (daily, weekly or monthly), and cost-allocation tags on every runner. |
What it costs, three ways.
GitHub-hosted runners bill every minute at GitHub's rate. Self-hosted runners on EC2 bill at AWS's rate, whether you run them with Actions Runner Controller, your own scripts or RunsOn. What RunsOn adds is a flat license that never counts minutes: €300 / $350 a year under 50k runners a month, €900 / $1,050 under 200k, €1,800 / $2,100 under 500k and €3,600 / $4,200 from 500k.
Linux x64, price per minute
| runner | GitHub-hosted | EC2 Spot + 30 GB gp3 | difference |
|---|---|---|---|
| 2 vCPU m8a.large on EC2 | $0.0060 | $0.0009 | 6.6× less on EC2 |
| 4 vCPU m8a.xlarge on EC2 | $0.0120 | $0.0014 | 8.9× less on EC2 |
| 8 vCPU c8id.2xlarge on EC2 | $0.0220 | $0.0022 | 10.2× less on EC2 |
| 16 vCPU c8id.4xlarge on EC2 | $0.0420 | $0.0039 | 10.7× less on EC2 |
GitHub list prices. EC2 Spot in us-east-1 (7-day average of the cheapest zone, as of Nov 2, 2026) plus the default 30 GB gp3 volume. On-demand fallbacks cost more. Every size and platform →
$6,300.00
150,000 minutes on 16-core Linux runners in a month, at GitHub's per-minute rate. There is nothing to run, and the bill grows with every minute.
$586.79 + your time
The same minutes on EC2 Spot, if you build the Spot handling yourself. Add the idle capacity you keep warm and the hours spent on the cluster, images and upgrades. RunsOn vs ARC →
$615.96
The same EC2 Spot and EBS, billed by AWS in your account, plus $29.17 a month of license. The control plane adds a few dollars a month on AWS.
From zero to the first job.
You need an AWS account with admin rights and someone who can install a GitHub App on your organization.
Launch the stack
Pick your region and create the CloudFormation stack with your
GitHub organization, license key and an email for alerts. It reaches
CREATE_COMPLETE in about 10 minutes.
Register the GitHub App
One click from the stack's outputs creates a private GitHub App for your organization. Its credentials stay in your AWS account.
Change the label
Replace ubuntu-latest with a RunsOn label
and push. Need Terraform or an existing VPC?
Use the module.
On GitHub Enterprise Server or GHE.com?
It's the same stack.
“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.”
When RunsOn is the wrong fit.
You aren't on AWS
RunsOn runs only on AWS. On GCP, Azure or your own hardware, look at Actions Runner Controller or GitHub's own runner agent.
You need macOS runners
AWS Mac instances come with a 24-hour minimum host allocation, which doesn't fit one machine per job.
You run a few minutes a month
GitHub's included minutes may cover you. The calculator shows where the license pays for itself.
Try it on one workflow.
The trial runs the real product in your AWS account for 15 days, then it's a flat license from €300 / $350 a year. RunsOn is bootstrapped and runs 5M+ jobs a day for 1,200+ companies.