Belum ada versi bahasa Indonesia, jadi tampil dalam bahasa Inggris.

What a self-hosted GitHub Actions runner really costs

Convika Team15 min read

  • ci
  • github-actions
  • self-managed
On this page

A self-hosted GitHub Actions runner costs nothing on GitHub's bill. GitHub's docs, read November 11, 2026, say runners "are free to use with GitHub Actions, but you are responsible for the cost of maintaining your runner machines." You pay for the server and in hours: updates, cleanup, security, and queues.

Fluxenic, the company behind Convika, makes Skipbox, a self-hosted runner it operates for you, so one option on this page is our own product. GitHub's rules below are quoted from GitHub's docs, and the server prices from Hetzner's pages, all read November 11, 2026 and linked under Sources.

The six costs of running your own runner

CostWhat it isWhat GitHub or the provider says
The serverA cloud VM or a dedicated server, rented by the monthHetzner CPX32, 4 vCPU and 8 GB: "€ 30.49 per month, excl. VAT"
A clean machine per jobWiping or rebuilding the machine so one job can't read the last one's files"You can then create your own automation that wipes the runner after it has been de-registered."
Runner updatesKeeping the runner application at a version GitHub still sends jobs to"you must update your runner version within 63 days of a newer version being made available"
SecurityKeeping pull requests away from anything on the machine worth stealingSelf-hosted runners "can be persistently compromised by untrusted code in a workflow"
QueueingOne runner runs one job. The rest wait, or you add runners"the job will remain queued until a runner comes online"
Your hoursEverything above, plus the OS, Docker, the disk, and the day it breaks"you are responsible for updating the operating system and all other software"

One more row belongs on the list when someone else takes these on:

OptionWho runs the machineWhat you pay
A managed self-hosted runner: Skipbox (made by Fluxenic, the company that publishes this site)Skipbox: your account's own VM, kept between jobs and cleaned after each oneA flat $39, $79, or $149 a month for 4, 8, or 16 vCPU, with unlimited minutes

What GitHub bills: nothing for the minutes

GitHub's billing page lists "Self-hosted runners" under usage that "remains free independently and does not reduce the included compute usage." A job on your own machine uses none of your plan's included compute.

GitHub announced a charge for self-hosted runners on December 16, 2025 and shelved it the next day. Nothing has been charged since. Are GitHub self-hosted runners free? has the sources.

GitHub's storage still bills when a self-hosted job uses it: artifacts past your plan's amount, and cache past 10 GB a repository.

The server

GitHub asks little of the machine: "The self-hosted runner application itself only requires minimal resources." Your jobs set the size.

Hetzner's published prices for 4, 8, and 16 vCPU, read November 11, 2026. Each is the lowest monthly price its page lists for that server, in euros before VAT:

vCPUShared vCPU (Regular Performance)Dedicated vCPU (General Purpose)
4CPX32: 8 GB, 160 GB disk, "€ 30.49 per month, excl. VAT"CCX23: 16 GB, 160 GB disk, "€ 73.49 per month, excl. VAT"
8CPX42: 16 GB, 320 GB disk, "€ 59.49 per month, excl. VAT"CCX33: 32 GB, 240 GB disk, "€ 117.99 per month, excl. VAT"
16CPX62: 32 GB, 640 GB disk, "€ 110.99 per month, excl. VAT"CCX43: 64 GB, 360 GB disk, "€ 234.99 per month, excl. VAT"

How to read the table:

  • Shared or dedicated. Hetzner says its Regular Performance servers are "based on shared resources," and labels them "Suited for workloads that can handle variable processor performance." Its label for General Purpose servers: "Dedicated resources that give you independence from the workload of other clients and projects." A build that holds every core for 20 minutes is the second kind of workload.
  • A dedicated server. Hetzner's AX42, an AMD Ryzen 7 PRO 8700GE with 64 GB, is "€ 99.00 per month, excl. VAT," plus a "€ 49.00 one-time setup fee, excl. VAT."
  • Left out. Hetzner's Cost-Optimized cloud servers were marked "not available" on November 11, 2026, so they aren't in the table.
  • One job per runner. A 4 vCPU server with one runner is one 4 vCPU job at a time.

For scale, GitHub's own Linux rates on private repositories that day: $0.006 a minute for the 2-core ubuntu-latest, $0.012 for 4-core, $0.022 for 8-core, and $0.042 for 16-core.

A clean machine per job

GitHub's docs say self-hosted runners "don't need to have a clean instance for every job execution." That cuts both ways:

  • What stays helps. Docker layers, package caches, and installed tools are on the disk when the next job starts.
  • What stays leaks. A checkout, an .npmrc with a token, or a container left running is there for the next job too.

GitHub's tool for a clean start is the ephemeral runner, which takes one job:

./config.sh --url https://github.com/octo-org --token example-token --ephemeral

GitHub's docs describe what happens next, and what is left to you: "The GitHub Actions service will then automatically de-register the runner after it has processed one job. You can then create your own automation that wipes the runner after it has been de-registered."

That automation is the real cost. You build the image, the script that rebuilds the machine, and the step that registers the next runner. A machine rebuilt for every job starts clean and starts empty: no layers, no package cache.

Runner updates

By default the runner application updates itself. GitHub's docs: "the runner application automatically updates itself when a job is assigned to the runner, or within a week of release if the runner hasn't been assigned any jobs."

GitHub's docs name one reason to turn that off: with ephemeral runners in containers, auto-update "can lead to repeated software updates when a new runner version is released." Then GitHub's rule applies, as its docs state it on November 11, 2026:

  • "If you disable automatic updates, you must update your runner version within 63 days of a newer version being made available."
  • "If you do not update your runner within 63 days of a new major, minor, or patch version becoming available, the GitHub Actions service will not assign jobs to it."
  • "If a critical security update is required, the service will not assign jobs until the runner is updated."

GitHub's changelog has given a shorter window. A note of March 17, 2026 says runners "on versions older than the latest release by more than 30 days" are "rejected from executing workflows as part of our standard runner deprecation process." The two pages disagree, so read the date for your version from the REST API: its runtime_deprecates_at field is "when runners on that version can no longer receive jobs."

There is a floor as well. On GitHub Enterprise Cloud, since September 29, 2026: "Self-hosted runners below version 2.329.0 won't be able to register or reregister."

The runner application is one piece. GitHub's docs: "you are responsible for updating the operating system and all other software." That means Docker, Node, Python, browsers, and compilers, which GitHub's hosted images ship for you.

Security on public repositories

GitHub's Secure use reference, in its own words:

  • "Self-hosted runners for GitHub do not have guarantees around running in ephemeral clean virtual machines, and can be persistently compromised by untrusted code in a workflow."
  • "As a result, self-hosted runners should almost never be used for public repositories on GitHub, because any user can open pull requests against the repository and compromise the environment."
  • "Similarly, be cautious when using self-hosted runners on private or internal repositories, as anyone who can fork the repository and open a pull request (generally those with read access to the repository) are able to compromise the self-hosted runner environment, including gaining access to secrets and the GITHUB_TOKEN."

GitHub also tells you what to check on the machine: "What sensitive information resides on the machine configured as a self-hosted runner?" and "Does the machine have network access to sensitive services?"

In practice: private repositories only, no long-lived keys on the machine, a network position where a compromised runner reaches nothing that matters, and a way to rebuild the machine on demand.

Queueing

A runner takes one job at a time. GitHub sends a job to "an online and idle runner that matches the job's runs-on labels and groups." When none is idle: "the job will remain queued until a runner comes online." And: "If the job remains queued for more than 24 hours, the job will fail."

Ways to run more at once:

  • Several runners on one machine. Each is its own registration. They share the CPU, the memory, the disk, and the Docker daemon, so two heavy jobs slow each other.
  • Several machines. Each one is another server to rent and patch.
  • Autoscaling. GitHub's reference implementation is Actions Runner Controller, "a Kubernetes operator that orchestrates and scales self-hosted runners for GitHub Actions." GitHub "recommends ARC for organizations with Kubernetes infrastructure and teams that have Kubernetes expertise," and says "autoscaling with persistent self-hosted runners is not recommended."

A stuck runner is a queue too. Nothing pages you when a job has waited an hour, unless you build the alert.

Your hours

The server has a price list. Your time doesn't, so write it down:

TaskHow often
Install and register the runner, as a service that survives a rebootOnce per machine
Build the wipe-and-rebuild automation, or accept a shared diskOnce, then every time it breaks
Update the runner application, if auto-update is offEvery release, inside GitHub's window
Patch the OS, Docker, and every tool your jobs callMonthly, and on security releases
Free the disk when images and build outputs fill itWhen a job fails with no space left
Find out why jobs are queuedWhen someone asks why CI is slow

Then: monthly cost = the server's rent + (your hours a month × what an hour of your time is worth). Set that beside your other options: your GitHub-hosted minutes times their rate, or a flat price.

The managed options, by who runs the machine

Read November 11, 2026. The options aren't ranked.

OptionWho runs the machineWho updates and cleans itPrice, as published
A server you rentYouYouThe server's rent, such as Hetzner's "€ 30.49 per month, excl. VAT" for CPX32, plus your hours
Actions Runner ControllerYou, on your Kubernetes clusterARC handles "the full lifecycle of runners within your cluster." The cluster is yours to runThe cluster's cost, plus your hours
ActuatedYou supply the servers. Actuated: "Fully managed control-plane, just add servers"Actuated's control plane, on your servers"Flat rate per server: $150 for the first, $125 for each additional," plus the servers
RunsOnYou, in your AWS accountRunsOn's software, in your account"Starter < 50k jobs/mo €300 / yr," and "AWS bills you for the instances at spot prices, with no markup"
GitHub-hosted runnersGitHubGitHub: each runner "is a new virtual machine"Per minute: $0.006 for Linux 2-core, $0.012 for 4-core, $0.022 for 8-core, $0.042 for 16-core
Skipbox (made by Fluxenic, the company that publishes this site)SkipboxSkipbox: credentials, the work directory, and containers wiped after every job; the runner and image kept currentA flat $39, $79, or $149 a month for 4, 8, or 16 vCPU, with unlimited minutes

What Skipbox takes off the list

Skipbox is a self-hosted runner you don't operate. Its VMs register with your GitHub organization or personal account as self-hosted runners, so GitHub bills none of their minutes.

  • The server. Each plan is a Linux x64 VM for your account alone: 4 vCPU and 8 GB, 8 vCPU and 16 GB, or 16 vCPU and 32 GB.
  • A clean start, with the caches kept. After every job, Skipbox wipes the runner's credentials, the work directory, every container, and credential files such as ~/.npmrc. Docker images and layers, package caches, and the tool cache stay on the disk.
  • Updates. The runner application and the image are Skipbox's to keep current. A machine that fails its health check after a job is rebuilt from a clean image.
  • Code from people without write access. A pull request from a fork, or a run started by someone without write access, runs on a new VM that is deleted afterward, not on your kept machine.
  • Queueing. A plan runs jobs up to its vCPU at once. More jobs wait, and waiting adds nothing to the bill.

Skipbox M is $79 a month however many minutes you run. On GitHub Team, which includes $18 a month, Skipbox M is cheaper than GitHub's 8-core runner above 4,410 job-minutes a month: ($79 + $18) ÷ $0.022. Skipbox S is cheaper than the 4-core runner above 4,750, and Skipbox L cheaper than the 16-core runner above 3,977.

What Skipbox doesn't do: macOS, Windows, Arm, or GPU jobs; jobs inside your private network; a job longer than 6 hours, where GitHub allows a self-hosted job 5 days. Run your own runner for those.

To try it, change one job's runs-on: line to skipbox and push. Skipbox's trial runs one 4 vCPU job at a time for 7 days or 3,000 job-minutes, whichever comes first, with no card.

Start a free Skipbox trial on skipbox.dev

For every runner sold at a fixed monthly price, see flat-rate GitHub Actions runners. For per-minute prices across vendors, see how much GitHub Actions runners cost. A runner that keeps its disk is also the last step in how to speed up GitHub Actions.

Frequently asked questions

How much does a self-hosted GitHub Actions runner cost?

GitHub bills nothing for it: its docs say self-hosted runners "are free to use with GitHub Actions, but you are responsible for the cost of maintaining your runner machines" (read November 11, 2026). The cost is the server, such as "€ 30.49 per month, excl. VAT" for Hetzner's 4 vCPU CPX32, plus your hours on updates, cleanup, and security. A service can run the machine instead: Skipbox is a self-hosted runner at a flat monthly price. Fluxenic, the company behind Convika, makes Skipbox.

Is it worth running your own GitHub Actions runner?

It takes the minutes off GitHub's bill: self-hosted minutes are free, and ubuntu-latest on a private repository is $0.006 a minute. The server and your time replace that bill. Add the server's rent to your hours a month at your own hourly rate, then set the sum beside your GitHub-hosted minutes times their rate.

How often do I have to update a self-hosted runner?

The runner application updates itself by default. With auto-update off, GitHub's docs say "you must update your runner version within 63 days of a newer version being made available," or GitHub stops assigning it jobs (read November 11, 2026). On GitHub Enterprise Cloud, runners below version 2.329.0 can't register since September 29, 2026. The OS and every tool your jobs use are yours to update.

Are self-hosted runners safe for public repositories?

GitHub says no: self-hosted runners "should almost never be used for public repositories on GitHub, because any user can open pull requests against the repository and compromise the environment" (Secure use reference, read November 11, 2026). On private repositories GitHub still says to "be cautious," because anyone who can open a pull request can run code on the machine.

Can a self-hosted runner run more than one job at a time?

No. One runner takes one job, and GitHub sends a job only to "an online and idle runner." To run jobs side by side you register several runners, on one machine or many, or you autoscale them. GitHub recommends Actions Runner Controller "for organizations with Kubernetes infrastructure and teams that have Kubernetes expertise."

Is there a managed self-hosted runner at a flat price?

Yes. Skipbox runs the machine and registers it with your GitHub account as a self-hosted runner, so GitHub bills none of its minutes. Skipbox is $39, $79, or $149 a month for 4, 8, or 16 vCPU with unlimited minutes. Each account gets its own VM, kept between jobs so Docker images and package caches stay, and wiped of credentials after every job. It runs Linux x64 jobs from public and private repositories, and a job moves with one line: runs-on: skipbox.

Sources

Read 2026-11-11 (Japan time).