Every job in GitHub Actions executes on a runner — a machine that pulls the job, runs its steps, streams logs, and reports the result. GitHub gives you three runner models with very different tradeoffs.
Option 1: GitHub-Hosted Runners
The default option specified by runs-on: ubuntu-latest / windows-latest / macos-latest. GitHub provisions a fresh VM per job, runs your steps, then destroys it.
Specifications (2026)
| OS | vCPU | RAM | Disk | Minute multiplier |
|---|---|---|---|---|
| Linux (ubuntu-latest) | 4 | 16 GB | 14 GB SSD | 1× |
| Windows (windows-latest) | 4 | 16 GB | 14 GB SSD | 2× |
| macOS (macos-latest) | 3 | 14 GB | 14 GB SSD | 10× |
Pre-installed software
Each image comes with hundreds of pre-installed tools: every major language runtime, Docker, kubectl, gh CLI, Terraform, AWS/Azure/GCP CLIs, browsers for end-to-end testing, etc. The full lists are maintained at github.com/actions/runner-images.
When GitHub-hosted is the right choice
- Open source projects (free, unlimited minutes for public repos)
- Small-to-medium private teams
- Workloads that fit comfortably in 4 vCPU / 16 GB
- You don't want to operate runner infrastructure
Option 2: Larger Runners
For builds that need more horsepower, GitHub sells larger runners — same managed model, beefier hardware:
| Size | vCPU | RAM |
|---|---|---|
| 4-core | 4 | 16 GB |
| 8-core | 8 | 32 GB |
| 16-core | 16 | 64 GB |
| 32-core | 32 | 128 GB |
| 64-core | 64 | 256 GB |
| 96-core | 96 | 384 GB |
ARM64 and GPU larger runners are also available. Pricing scales linearly with size. Specify them with a custom runs-on label configured in your org/repo settings.
Option 3: Self-Hosted Runners
You install the runner agent on your own machine — bare metal, VM, container, or Kubernetes pod. Jobs queued with the matching label dispatch to your runners.
# From your repo Settings → Actions → Runners → New self-hosted runner
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64.tar.gz -L https://github.com/actions/runner/releases/download/...
tar xzf actions-runner-linux-x64.tar.gz
./config.sh --url https://github.com/myorg/myrepo --token AABB...
./run.sh
When self-hosted makes sense
- Heavy compilation workloads where GitHub minutes get expensive (>$1000/month)
- Builds requiring GPUs you already own
- Access to internal networks (VPN, private package registries)
- Specialised hardware (FPGAs, dedicated databases)
- Compliance requirements that prohibit cloud-managed runners
Self-hosted security warning
The runner agent runs whatever code your workflows tell it to run. If you attach a self-hosted runner to a public repo, any contributor can submit a PR that runs arbitrary code on your infrastructure. GitHub explicitly recommends against this. For public repos, use only GitHub-hosted runners.
Ephemeral vs persistent
The recommended pattern for self-hosted is ephemeral runners — each runner accepts one job, then exits. This eliminates job-to-job state leakage. Implementations:
- actions-runner-controller (ARC): Kubernetes operator that spins up runner pods on demand
- Auto-scaling EC2/Azure VM: CloudFormation/Terraform templates
- Plain Docker: spawn a container per job
Runner Groups
For organizations and enterprises, runners can be grouped (e.g., "production-runners", "ml-gpu-runners") with access policies controlling which repos/workflows can dispatch jobs to them. This is how mature organisations safely share runner fleets.
Container Jobs
An orthogonal concern: regardless of where your runner lives, you can ask a job to execute inside a Docker container on that runner:
jobs:
test:
runs-on: ubuntu-latest
container:
image: node:20-alpine
steps:
- uses: actions/checkout@v4
- run: npm ci && npm test
This gives you reproducible environments without managing a specialised runner image.
Choosing a Model
| Workload | Best runner |
|---|---|
| OSS project, GitHub Actions tutorial | GitHub-hosted (free for public) |
| Startup with 10 engineers | GitHub-hosted, occasionally larger |
| Heavy nightly builds, predictable spend > $1500/mo | Self-hosted ephemeral (ARC on Kubernetes) |
| Mac builds for iOS | GitHub-hosted macOS (specialised hardware otherwise painful) |
| Build inside corporate VPN | Self-hosted inside the VPN |
| GPU training a few times per week | Larger runners with GPUs |
Most teams start GitHub-hosted, monitor minute consumption, and migrate hot workloads to self-hosted only when economics dictate. Premature self-hosting is a common operational mistake.