RunsOn pays for itself at 49 jobs a day
What a RunsOn stack costs before it runs a single job, for Flex and Fleet, and the job volume where it beats GitHub-hosted runners.
The next, more important question after someone learns how much they’d save using RunsOn, is how much they’d spend to keep the thing running since its fully self-hosted on your own AWS.
So we’ve not only answered that question by breaking down every thing you pay for, fixed or otherwise, but also show how many runners it takes for those costs to break even against what’d you’d pay to GitHub.
And it’s not a lot.
The fixed bill#
This is everything on AWS that’s not the runner compute itself, and the license.
| Jobs/day | License tier | License | Flex AWS | Fleet AWS | Flex total | Fleet total |
|---|---|---|---|---|---|---|
| 500 | Starter | $29 | $7 | $6 | $36 | $36 |
| 1,000 | Starter | $29 | $8 | $7 | $37 | $36 |
| 5,000 | Growth | $88 | $12 | $8 | $100 | $96 |
| 10,000 | Scale | $175 | $19 | $10 | $194 | $185 |
| 20,000 | Enterprise | $350 | $34 | $17 | $384 | $367 |
| 50,000 | Enterprise | $350 | $77 | $34 | $427 | $384 |
The license is a flat annual fee that steps with how many runners you launch per month:
- $350/year for under 50,000 jobs
- $1,050/year for under 200,000 jobs
- $2,100/year for under 500,000 jobs
- $4,200/year for over 500,000 jobs.
One license covers Flex and Fleet, so running both does not add a second licence.
The AWS part is small because the control plane is small. Flex and Fleet each run one arm64 Fargate Spot task, 0.25 vCPU and 0.5 GB until you are past 10,000 jobs a day. Here’s everything that makes up the fixed control plane:
| Per month | Flex @ 1,000/day | Fleet @ 1,000/day | Flex @ 50,000/day | Fleet @ 50,000/day |
|---|---|---|---|---|
| ECS Fargate Spot task (arm64) | $2.26 | $2.26 | $4.53 | $4.53 |
| Public IPv4 for the task | $3.60 | $3.60 | $3.60 | $3.60 |
| Secrets Manager | $0.80 | $0.40 | $0.80 | $0.40 |
| CloudWatch dashboard | free | free | free | free |
| API Gateway (webhook ingress) | $0.42 | – | $21.00 | – |
| Lambda | free | free | $1.30 | $0.10 |
| SQS (FIFO) | free | – | $8.50 | – |
| DynamoDB (on-demand) * | $0.64 | $0.41 | $31.88 | $20.63 |
| CloudWatch Logs ingestion * | free | free | $5.00 | $5.00 |
| AWS control plane | $7.72 | $6.68 | $76.60 | $34.25 |
| License (Starter / Enterprise) | $29.17 | $29.17 | $350.00 | $350.00 |
| Fixed total | $36.89 | $35.84 | $426.60 | $384.25 |
us-east-1 list prices, 30-day month. Webhook, Lambda and SQS volumes use the same per-job assumptions as the v3 control-plane estimate: 4 webhooks per job, 100 ms per Lambda invocation, 3 queue requests per webhook. Lines marked * are not measured. They assume 30 DynamoDB write units per job on Flex and 20 on Fleet, and 10 KB of control-plane logs per job.
What is not in these numbers: WAF if you turn it on, whatever you keep in the S3 cache bucket, private IPs if in private mode and warm pools, which are runner time you choose to pay for.
Where it crosses GitHub#
Pick a platform, an instance and a runner size, and the chart shows both bills across job volume and the break-in point.
m8i.large at $0.0006/min spot against GitHub's 2-vCPU runner at $0.006/min.
| Jobs/day | GitHub | Runner time | Fixed | RunsOn total | Saved / month | Ratio |
|---|---|---|---|---|---|---|
| 500 | $450 | $82 | $36 | $119 | $331 | 3.8× |
| 1,000 | $900 | $165 | $37 | $202 | $698 | 4.5× |
| 5,000 | $4,500 | $824 | $100 | $924 | $3,576 | 4.9× |
| 10,000 | $9,000 | $1,649 | $194 | $1,842 | $7,158 | 4.9× |
| 20,000 | $18,000 | $3,298 | $384 | $3,682 | $14,318 | 4.9× |
| 50,000 | $45,000 | $8,244 | $427 | $8,671 | $36,329 | 5.2× |
us-east-1 list prices, 30-day month. RunsOn runner time includes a 30 GB gp3 root volume, a public IPv4 and the boot time AWS bills but GitHub doesn't (30 s on Linux). Fixed costs are the control plane on Fargate Spot, net of the AWS free tier, plus the license. Both axes are logarithmic.
The arithmetic behind each line:
GitHub, per job = job minutes × GitHub's per-minute rateRunsOn, per job = (job minutes + boot) × (EC2 + EBS + public IPv4 per minute)RunsOn, monthly = jobs × per job + fixed bill aboveRunsOn is charged for the time the instance spends booting, which GitHub does not bill, so the model adds 30 seconds to every Linux job and 2.5 minutes to every Windows job. It also charges every runner-minute for a 30 GB gp3 root volume at 400 MB/s and a public IPv4 address.
Want your own numbers instead of an average? The calculator takes minutes per platform, and the pricing page lists every runner size.