self-host →

Quickstart

From zero to a cached, 10x-cheaper GitHub Actions build running in your own AWS account.

This quickstart takes you from nothing to a fast, cached GitHub Actions build running on your own AWS account in about 15 minutes. Three steps: install RunsOn in your AWS account, point a workflow at it, then make it fast with caching.

You’ll need an AWS account (ideally a dedicated sub-account for isolation) and a RunsOn license keyfree for non-commercial use, or a 15-day trial.

Most teams start with RunsOn Flex, which gives each job precise control over its runner. Platform teams add RunsOn Fleet on top to publish a small set of standardized runner fleets. The tabs below show both — Flex is the recommended start.

1. Install RunsOn in your AWS account

Flex installs with a single CloudFormation stack in about 10 minutes:

  1. Pick your AWS region to open the CloudFormation quick-create screen with the RunsOn template pre-loaded.
  2. Fill in your GitHub organization name, license key, and a notification email, then submit. RunsOn creates a dedicated, least-privilege IAM role for the service.
  3. From the stack Outputs, open the RunsOnEntryPoint URL and click Register app — this creates a private GitHub App that lives only in your AWS account.
Flex install guide Full step-by-step walkthrough with screenshots, including how to enable repository-level runners.

Fleet installs as infrastructure-as-code with the official Terraform / OpenTofu module:

module "runs_on_fleet" {
source = "runs-on/runs-on/aws//modules/fleet"
version = "v3.1.0"
# github boundary, networking, runner fleets...
}
Fleet install guide Full Terraform / OpenTofu walkthrough — variables, networking, and runner fleets.

2. Run your first job on RunsOn

Swap GitHub’s hosted label for a RunsOn label — that’s the only required change:

runs-on: ubuntu-latest
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64

A complete minimal workflow:

jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64
steps:
- uses: actions/checkout@v6
- run: echo "Hello from RunsOn"

The label is composable — request exactly the machine you want, for example cpu=4/ram=16/family=c7a+m7a or runner=16cpu-linux-arm64. See all job labels and Linux runners.

jobs:
build:
runs-on: runs-on/fleet=linux-small/env=production
steps:
- uses: actions/checkout@v6
- run: echo "Hello from RunsOn Fleet"

With Fleet, the platform team publishes approved runner fleets and workflow authors target them by name. See runner fleets.

Turn on Magic Cache by adding extras=s3-cache to your runner label, then keep using the standard actions/cache action — no other workflow changes. RunsOn transparently routes the cache to a fast, in-VPC S3 backend:

  • 5x faster than the official GitHub Actions cache.
  • Unlimited size (items evicted by your stack’s policy, default 10 days).
  • Local to your VPC, so it’s fast, reliable, and secure.
jobs:
build:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64/extras=s3-cache
steps:
- uses: runs-on/action@v2
- uses: actions/cache@v5
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

For Fleet, publish runners with Magic Cache enabled from Terraform, then keep using actions/cache in your workflows:

runners = {
linux-cache = {
cpu = 4
ram = 8
family = ["c8i"]
image = "ubuntu24-full-x64"
extras = ["s3-cache"]
}
}

Learn more in the Magic Cache reference.

The same extras=s3-cache runner also accelerates Docker builds. Point Buildx at the type=gha cache backend and RunsOn routes it to S3 transparently:

jobs:
docker:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64/extras=s3-cache
steps:
- uses: runs-on/action@v2
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
cache-to: type=gha,mode=max
cache-from: type=gha

Next steps