GitHub Actions Compute Resources and Parallelism
Default Runner Specs
GitHub Actions provides GitHub-hosted runners — cloud VMs managed by GitHub — out of the box.
Standard Runners
| Label | OS | vCPU | RAM | Storage | Architecture |
|---|---|---|---|---|---|
ubuntu-latest / ubuntu-24.04 | Ubuntu 24.04 LTS | 4 | 16 GB | 14 GB SSD | x86_64 |
ubuntu-22.04 | Ubuntu 22.04 LTS | 4 | 16 GB | 14 GB SSD | x86_64 |
windows-latest / windows-2022 | Windows Server 2022 | 4 | 16 GB | 14 GB SSD | x86_64 |
macos-latest / macos-15 | macOS 15 | 3 | 7 GB | 14 GB SSD | ARM64 (M1) |
macos-13 | macOS 13 | 4 | 14 GB | 14 GB SSD | x86_64 (Intel) |
ubuntu-latestoffers the best cost-performance ratio and is the standard choice for most CI/CD workloads. macOS runners consume minutes at a higher multiplier (see below).
Minute Multipliers
GitHub Actions free and paid tiers consume minutes, but the cost multiplier varies by OS.
| OS | Multiplier |
|---|---|
| Linux | 1× |
| Windows | 2× |
| macOS (Intel) | 10× |
| macOS (ARM64) | 5× |
Concurrency Limits by Plan
Concurrent Jobs (GitHub-Hosted Runners)
The number of jobs that can run simultaneously depends on your plan.
| Plan | Linux/Windows Concurrency | macOS Concurrency |
|---|---|---|
| Free | 20 | 5 |
| Pro | 40 | 5 |
| Team | 60 | 50 |
| Enterprise | 500 (default; can be increased) | 50 |
| Public repositories | Effectively unlimited | Effectively unlimited |
Public repositories benefit from GitHub's generous free tier with virtually no concurrency restrictions.
Self-Hosted Runner Concurrency
When using self-hosted runners, concurrency is limited only by the number of registered runner instances — there are no plan-based caps.
How Parallelism Works
Matrix Strategy
The simplest parallelization mechanism. GitHub generates one job per combination of matrix variables.
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
max-parallel: 4 # cap simultaneous jobs (omit to run all combinations in parallel)
fail-fast: false # continue other jobs even if one fails
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
- Up to 256 jobs per matrix
- Use
include/excludeto add or remove specific combinations
Parallel Jobs Within a Workflow
Jobs without a needs dependency run in parallel by default.
jobs:
lint:
runs-on: ubuntu-latest
steps: [...]
unit-test:
runs-on: ubuntu-latest
steps: [...]
build:
needs: [lint, unit-test] # waits for both lint and unit-test to finish
runs-on: ubuntu-latest
steps: [...]
Concurrency Groups
Prevent redundant runs on the same branch or PR.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # cancel older runs when a new one is triggered
Ways to Scale Up Compute
1. Larger Runners
GitHub provides beefier hosted runners at a higher cost. Requires Team or Enterprise plan.
Linux Larger Runners
| vCPU | RAM | Storage |
|---|---|---|
| 4 | 16 GB | 14 GB |
| 8 | 32 GB | 300 GB |
| 16 | 64 GB | 300 GB |
| 32 | 128 GB | 2.9 TB |
| 64 | 256 GB | 2.9 TB |
Windows Larger Runners
Equivalent specs to Linux (4–64 vCPU).
GPU Runners
NVIDIA Tesla T4 GPU runners are available for Enterprise plans.
jobs:
heavy-build:
runs-on: ubuntu-latest-16-cores # 16 vCPU larger runner
steps:
- uses: actions/checkout@v4
- run: make build
Larger runner labels are created and managed under Organization Settings > Actions > Runners.
2. Self-Hosted Runners
Install the GitHub Actions runner agent on your own infrastructure (on-prem servers, cloud VMs, containers).
Advantages
- Full control over hardware specs (including dedicated physical servers)
- Direct access to internal network resources (databases, private registries, etc.)
- Long-running builds do not consume GitHub-billed minutes
Disadvantages
- You are responsible for infrastructure maintenance and security
- Not recommended for public repositories (risk of malicious code execution from forks)
jobs:
build:
runs-on: self-hosted # any registered self-hosted runner
# or
runs-on: [self-hosted, linux, x64, high-memory] # filter by labels
Ephemeral Self-Hosted Runners with ACA Jobs
For a cost-efficient pattern that spins up runners only when a job needs them, see ACA Job Self-Hosted Runner.
3. Combining with Docker Build Cloud
If Docker image builds are the bottleneck, Docker Build Cloud offloads builds to Docker's cloud infrastructure, reducing the dependency on runner specs.
Best Practices
Leverage Caching
Caching dependency downloads can cut minutes off every run.
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
| Ecosystem | Cache Path | Key Source |
|---|---|---|
| npm | ~/.npm | Hash of package-lock.json |
| NuGet (.NET) | ~/.nuget/packages | Hash of *.csproj |
| pip (Python) | ~/.cache/pip | Hash of requirements.txt |
| Docker layers | /tmp/.buildx-cache | Hash of Dockerfile |
Parallelize Independent Work
# Bad: everything runs sequentially
lint → unit-test → integration-test → e2e-test → build → deploy
# Good: independent tasks run in parallel
lint ─┐
├→ build → deploy
unit-test ─┘
integration-test (separate parallel job)
Set Timeouts
The default timeout is 6 hours. Set a realistic upper bound to avoid runaway jobs.
jobs:
build:
timeout-minutes: 30
Choosing the Right Runner
| Scenario | Recommended Runner |
|---|---|
| Standard CI (tests, lint, build) | ubuntu-latest (cheapest, fast) |
| Windows app build/test | windows-latest |
| iOS/macOS app build | macos-latest |
| High-memory workloads (ML, large builds) | Larger runners (16–64 cores) |
| Internal network access required | Self-hosted runner |
| Docker build acceleration | Combine with Docker Build Cloud |
Security
- Never use self-hosted runners on public repositories (risk of arbitrary code execution from forked PRs)
- Store secrets in repository, Organization, or Environment Secrets
- Minimize
GITHUB_TOKENpermissions with explicitpermissions
permissions:
contents: read
pull-requests: write
Comparison with Azure DevOps Pipelines
GitHub Actions and Azure DevOps Pipelines share similar concepts, but their compute resource design philosophies differ in meaningful ways.
Microsoft-Hosted Agent Specs
| Item | GitHub Actions (Standard) | Azure DevOps (Standard) |
|---|---|---|
| Linux | ubuntu-latest: 4 vCPU / 16 GB | ubuntu-latest: 2 vCPU / 7 GB |
| Windows | 4 vCPU / 16 GB | 2 vCPU / 7 GB |
| macOS | 3–4 vCPU / 7–14 GB | 3 vCPU / 14 GB (extra cost) |
| Storage | 14 GB SSD | 10 GB SSD |
GitHub Actions has higher default specs (4 vCPU / 16 GB vs 2 vCPU / 7 GB for Azure DevOps).
Parallelism Model
| Item | GitHub Actions | Azure DevOps |
|---|---|---|
| Parallel unit | Job | Pipeline Run |
| How concurrency is managed | Included in plan (20–500 concurrent jobs) | Parallel Jobs purchased separately |
| Free tier | 2,000 min/month + 20 concurrent jobs | Public: unlimited; Private: 1 parallel job only |
| Scaling cost | Plan upgrade or larger runners | $40/month per additional parallel job |
Azure DevOps treats parallel job count as an explicit, separately purchased resource. GitHub Actions bundles generous concurrency into each plan tier, making it easier to get started.
Agent/Runner Management
| Item | GitHub Actions | Azure DevOps |
|---|---|---|
| Hosted resource grouping | Runner Groups (Org or Enterprise) | Agent Pools (Org or Project) |
| Self-hosted registration | Repository / Org / Enterprise | Agent Pool |
| Auto-scaling | Larger runners or self-hosted scale-out | Scale Set Agents (VMSS) with autoscale |
| Ephemeral instances | ACA Jobs or ephemeral runner actions | VMSS agents launch per job |
YAML Comparison
# GitHub Actions
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: dotnet build
# Azure DevOps Pipelines
jobs:
- job: Build
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
- script: dotnet build
The structure is nearly identical. The key difference is in the ecosystem: GitHub Actions uses Actions (uses), while Azure DevOps uses Tasks (task).
Which to Choose
| Priority | Recommendation |
|---|---|
| Code is already on GitHub | GitHub Actions (seamless integration) |
| Heavy use of Azure services | Azure DevOps (rich service connections and environment management) |
| Maximize free concurrency | GitHub Actions (20 concurrent jobs on free tier) |
| Enterprise governance | Azure DevOps (granular project/team/approval-gate management) |
| Higher default hosted runner specs | GitHub Actions (4 vCPU / 16 GB by default) |
Summary
GitHub Actions Compute Resources — Quick Reference
Default spec: ubuntu-latest = 4 vCPU / 16 GB RAM
Concurrency: Free=20, Pro=40, Team=60, Enterprise=500 concurrent jobs
Parallelism: Matrix strategy / parallel jobs / concurrency groups
Scaling up: Larger runners (4–64 vCPU) / self-hosted runners
Cost efficiency: Cache dependencies / set timeouts / choose the right OS
GitHub Actions excels at "high specs out of the box with minimal setup." Azure DevOps excels at "granular project governance and approval workflows." The two are also frequently used together — hosting code on GitHub while deploying via Azure Pipelines is a common hybrid architecture.