quickstart →

GPU runners for GitHub Actions: options, pricing and setup

Run GitHub Actions jobs on a GPU: GitHub's T4 runner and its limits, self-hosted GPU runners, and EC2 GPU runners with RunsOn, with prices and examples.

Standard GitHub-hosted runners have no GPU, so a job that trains a model, runs CUDA kernels, or tests a GPU code path needs a different runner. There are three ways to get one:

OptionGPUsPlansPrice per minute
GitHub GPU larger runner1× NVIDIA Tesla T4 (16 GB)Team, Enterprise Cloud$0.052
Self-hosted runner on your own GPU machineWhatever you ownAnyYour hardware
RunsOn on EC2, in your AWS accountT4, A10G, L4, L40S, V100, A100, H100, H200…Any, including FreeFrom $0.0047 (T4, spot)

GitHub’s GPU runner#

GitHub offers one GPU size as a larger runner: 4 vCPUs, 28 GB of RAM, 176 GB of SSD and one NVIDIA Tesla T4 with 16 GB of VRAM, on Ubuntu or Windows. To set it up, an organization admin creates a new GitHub-hosted runner, picks a GPU-optimized image (NVIDIA’s image from the Partner tab, with the drivers installed) and a size from the GPU-powered tab, then jobs target it by name:

.github/workflows/ci.yml
jobs:
cuda-tests:
runs-on: linux-gpu-t4 # the name given to the runner
steps:
- uses: actions/checkout@v7
- run: nvidia-smi
- run: make test-cuda

What to know before choosing it:

  • Team or Enterprise Cloud only, billed from the first minute (included minutes don’t apply).
  • One GPU, one model. The T4 is a 2018 inference card: fine for CUDA unit tests and small models, slow for training anything sizeable, and there’s no multi-GPU size.
  • At most 100 concurrent GPU jobs per organization or enterprise.
  • Price: at $0.052 a minute, a 30-minute nightly job costs about $47 a month.

Self-hosted GPU runners#

Any machine with an NVIDIA GPU, the driver and the runner application can run GPU jobs. Register it with a label such as gpu and target runs-on: [self-hosted, linux, gpu]. Install the NVIDIA Container Toolkit too if jobs use containers (docker run --gpus all).

This is the cheapest route for a GPU workstation you already own. On cloud GPUs it’s often the most expensive one: a GPU instance left running between jobs costs dollars an hour while idle, so you need ephemeral runners that start per job and stop afterwards. Don’t attach a persistent GPU runner to a public repository.

GPU runners with RunsOn#

RunsOn starts an EC2 instance in your AWS account for each job and terminates it when the job ends, so you pay only for the minutes used, at AWS prices. Pick the GPU instance and a GPU image (NVIDIA driver, CUDA toolkit and container toolkit preinstalled) in the label:

.github/workflows/ci.yml
jobs:
cuda-tests:
runs-on: runs-on=${{ github.run_id }}/family=g4dn.xlarge/image=ubuntu24-gpu-x64
steps:
- uses: actions/checkout@v7
- run: nvidia-smi
- run: make test-cuda

Typical GPU runners, with their 7-day average spot price in us-east-1 (instance plus disk):

RunnerInstanceSpot / minOn-demand / min
4cpu·T4g4dn.xlarge$0.0047$0.0091
8cpu·T4g4dn.2xlarge$0.0049$0.013
16cpu·A10g5.4xlarge$0.013$0.027
48cpu·4×T4g4dn.12xlarge$0.023$0.066

Larger cards (L4 on g6, L40S on g6e, A100 and H100 on p4d and p5) work the same way, if your AWS account has the quota for them. GPU quotas start at zero in new accounts, so request them before the first job. See GPU runners in the docs for images, quotas and examples.

Running GPU tests without wasting GPU minutes#

A GPU minute costs several times a CPU minute, so keep the GPU job small:

.github/workflows/ci.yml
on:
pull_request:
schedule:
- cron: "0 3 * * *" # nightly full run
jobs:
cpu-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: pytest -m "not gpu"
gpu-tests:
needs: cpu-tests # don't pay for a GPU if the cheap tests fail
if: github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'gpu')
runs-on: runs-on=${{ github.run_id }}/family=g4dn.xlarge/image=ubuntu24-gpu-x64
timeout-minutes: 60
steps:
- uses: actions/checkout@v7
- run: nvidia-smi
- run: pytest -m gpu
  • Run CPU tests first and the GPU job only after they pass (needs).
  • Run the full GPU suite nightly, and on pull requests only when asked (a gpu label).
  • Set timeout-minutes so a hung kernel doesn’t burn the default 6 hours.
  • Build and cache Docker images and model weights outside the GPU job: downloading a 10 GB model on every run costs GPU minutes. See caching.
  • Check that the GPU is there before running anything expensive: nvidia-smi fails fast when the driver or the device is missing.