What the runner needs
| Requirement | GitHub's reference |
|---|---|
| Linux | Ubuntu 20.04+, Debian 10+, RHEL 8+, Fedora 29+ and others |
| Architecture | x64; ARM64 in public preview |
| Network | Outbound HTTPS on port 443; at least 70 kbit/s up and down |
| Queue limit | A job queued for more than 24 hours fails |
| Updates | GitHub updates the runner application; the OS and toolchains are yours |
The runner connects out to GitHub and waits for work, so the machine needs no inbound port at all beyond SSH for you. Size it for the build, not the runner: the agent is light, and compilers, containers and test suites set the vCPU and memory figure.
Cost: free jobs, your machine
GitHub's documentation describes self-hosted runners as free to use with GitHub Actions; you carry the cost of the machine. In December 2025 GitHub announced a per-minute platform charge for self-hosted runner usage, then postponed it to re-evaluate; check GitHub's billing documentation for the current position before you plan around it.
That leaves one question: how the machine is billed. A runner that is busy all month suits a fixed monthly plan. A runner used in bursts, for a release, a nightly build or a batch of tests, suits a machine billed only while it runs.
Elastic VPS: billed while it runs
The elastic plans on our Cloud VPS are billed the EC2 way: compute per second while the machine runs, and its disk and IPv4 address every hour it exists, running or stopped. Outbound traffic is billed per GB with no allowance and no throttle; inbound is free. Nothing is paid up front: a card is saved, usage is invoiced at month end, and a machine can be released from the dashboard at any time.
It is a KVM virtual machine on an OpenStack host in New York that other customers share; vCPUs are not pinned. That is fine for most CI work. For builds that need guaranteed cores, a dedicated server runs the same runner on a whole machine, and a GPU server takes CUDA jobs. Systems are Ubuntu, Debian, AlmaLinux and Rocky Linux from official cloud images; there is no Windows.
Setting up an ephemeral runner
- In the repository, open Settings, Actions, Runners, New self-hosted runner, choose Linux x64, and run the download commands shown there as an unprivileged user.
- Configure with the URL and the registration token from that page. The token expires after one hour.
- Add
--ephemeralso the runner takes one job and deregisters; reset or rebuild the machine before registering again. - For a long-lived runner instead, install the bundled service so it starts on boot.
./config.sh --url https://github.com/OWNER/REPO --token "$RUNNER_TOKEN" --ephemeral --labels vps,linux
./run.sh
# long-lived runner as a service instead:
sudo ./svc.sh install
sudo ./svc.sh start
Target it from a workflow with runs-on: [self-hosted, linux, vps]. GitHub recommends autoscaling with ephemeral runners, or just-in-time runners created through the REST API.
Security rules that matter
- GitHub's hardening guide says self-hosted runners should almost never be used for public repositories: anyone who can open a pull request could run code on the machine.
- A non-ephemeral runner can be persistently compromised by untrusted workflow code. Prefer ephemeral runners, or rebuild the VPS on a schedule.
- Keep secrets on the machine to a minimum; another job on the same runner can see command-line arguments.
- Firewall all inbound traffic except SSH. The runner needs none.
When GitHub-hosted runners are better
For public repositories, macOS or Windows builds, or a handful of short jobs a month, GitHub's own runners are simpler and safer. A self-hosted runner pays off with private repositories, long builds, caches that should survive between jobs, or access to resources on your own network.
Questions
Does GitHub charge for self-hosted runner minutes?
GitHub's documentation describes self-hosted runners as free to use; you pay for the machine. A per-minute platform charge announced in December 2025 was postponed, so check GitHub's billing docs for the current position.
Which ports does a self-hosted runner need?
Outbound HTTPS on port 443 to GitHub. The runner needs no inbound port, so the firewall can drop everything except your SSH.
Can I use a self-hosted runner on a public repository?
GitHub's hardening guide says they should almost never be used for public repositories, because anyone who opens a pull request could run code on the machine.
What is an ephemeral runner?
A runner registered with --ephemeral: it processes one job and GitHub deregisters it, so the machine can be reset before the next job. GitHub recommends them for autoscaling.
How long is the registration token valid?
One hour. Generate a new one from Settings, Actions, Runners, or through the REST API, when you register a runner.
Can the runner build Windows or macOS targets?
Not on our Cloud VPS, which offers Ubuntu, Debian, AlmaLinux and Rocky Linux only. Use GitHub-hosted runners for those, or a dedicated server with Windows.