Why run your own runner?
Usually for one of three reasons: builds that take a long time, caches you want to keep between jobs, or access to things only your own servers can reach. The runners GitHub provides are easier for small projects, but each job begins on a fresh machine.
What about cost? GitHub says jobs on your own runners cost nothing in Actions; the machine is your expense. Late in 2025 GitHub planned a small per-minute fee for these runners, then paused the plan to think again, so look at GitHub's billing page for the latest before you budget.
What does the machine need?
- A supported system: recent Ubuntu, Debian, Red Hat, Fedora and similar Linux, on 64-bit Intel or AMD (ARM is in preview).
- Network: outbound HTTPS on port 443 and at least 70 kbit/s each way. The runner calls GitHub, so nothing has to reach in.
- Enough power for your build: the runner itself is tiny; your compiler, tests and containers decide how many vCPUs and how much memory you want.
- Patience in the queue: a job that waits more than 24 hours for a free runner fails.
Pay only while it works
Most runners sit idle between pushes, which is why our Elastic Cloud VPS suits them: you are charged for processing time by the second, only while the server is switched on, while storage and the IPv4 address are charged hourly for as long as you keep the server. Outbound traffic is paid per GB and inbound is free. Nothing is due up front; you save a card, usage is invoiced at the end of the month, and you can release the machine from your dashboard whenever you like.
If your runner will be busy around the clock, the fixed monthly Cloud VPS plans on the same page are the better deal. Both are virtual machines in New York, on shared hosts with unpinned vCPUs, running Ubuntu, Debian, AlmaLinux or Rocky Linux. Need a whole machine for heavy builds? See our dedicated servers.
Up and running in an evening
- Order an Elastic VPS with Ubuntu, log in over SSH as root, and create a normal user to install and run the runner under, rather than running it as root.
- On GitHub, open your repository's Settings, then Actions, then Runners, and click New self-hosted runner. Choose Linux and copy the download commands it shows.
- Run the
config.shcommand it gives you. The registration token in it is only valid for an hour, so do this straight away. - Add
--ephemeralif you want each runner to take a single job and then remove itself. - Start it with
./run.sh, or install it as a service withsudo ./svc.sh installandsudo ./svc.sh startso it survives reboots.
In your workflow file, send jobs to it with runs-on: self-hosted, plus any labels you gave it.
Keeping it safe
GitHub is clear on the big one: keep self-hosted runners away from public repositories, almost without exception, since a stranger's pull request could end up executing on your server. Beyond that:
- Prefer ephemeral runners. A runner that keeps going between jobs can be left compromised by one bad workflow.
- Store as few secrets there as you can, because a later job on that runner may be able to read what an earlier one passed on its command line.
- Block all incoming connections except SSH. The runner only ever talks out to GitHub.
- Keep the operating system patched. GitHub updates the runner program, not the rest of the machine.
When GitHub's own runners are the better choice
For an open-source project, Windows or macOS builds, or a few quick checks a month, stick with the runners GitHub provides. Our Cloud VPS offers Linux only. If you would rather host the whole code platform yourself, our GitLab guide walks through that instead.
Questions people ask
- Do I pay GitHub to use my own runner?
- Not today: GitHub lists jobs on your own runners as free, and you cover the server. It had planned a per-minute charge from 2026 and put it on hold, so have a look at GitHub's billing pages for any change.
- Do I need to open any ports?
- No incoming ones. The runner makes outbound HTTPS connections to GitHub on port 443, so you can block everything coming in except your own SSH.
- Can I use it for my public open-source project?
- GitHub advises against it. On a public project, any outsider sending a pull request could have their code executed on your server.
- What does --ephemeral do?
- It tells the runner to take one job and then deregister. For each build to start clean, you still have to reset or rebuild the machine between jobs, for example by reinstalling it from the dashboard. GitHub recommends ephemeral runners when you scale runners up and down.
- Does an elastic VPS cost anything when stopped?
- Yes, a little. Processing time stops being billed, but the disk and IPv4 address are billed every hour the machine exists. Release it from the dashboard to stop those too.
- My registration token stopped working. Why?
- Tokens expire one hour after GitHub creates them. Open Settings, Actions, Runners again to get a fresh one.