SKIP_TO_MAIN_CONTENT
machine.dev
SIGN_UP
04.0 // Documentation v1.8.4 Last updated 2026-06-05

Configuration Options

Complete reference for every label you can pass to runs-on with machine.dev. CPU and GPU types, architecture, tenancy, regions, storage, metrics.

This page is the canonical reference for every selector you can pass to runs-on: with machine.dev. For pricing see Pricing; for which workload fits which runner see CPU vs GPU.

Label format

machine.dev reads everything it needs from the label in runs-on:. Pack every selector into a single label string, led by machine and separated by /:

runs-on: machine/gpu=l4/tenancy=spot

Rules:

  • Always lead with machine. GitHub only routes a job to machine.dev when the label carries the machine sentinel, so every packed label starts with it.
  • Separate selectors with /. Each key=value segment is one selector. machine/cpu=16/tenancy=spot/regions=us-east-1 requests a 16-vCPU spot runner pinned to us-east-1.
  • Multi-value regions puts the commas inside the value: machine/gpu=l4/regions=us-east-1,us-east-2.

Pin one runner to one job with id=

Add id=${{ github.run_id }} to tie the runner to a specific workflow run. machine.dev registers the runner with GitHub using the exact label the job requested — including the unique id — so the runner matches only that job:

runs-on: machine/id=${{ github.run_id }}/gpu=l4/tenancy=spot

This is the recommended form when many jobs run at once. Without a unique value in the label, GitHub can hand a queued job to any idle runner whose labels are a superset of the job’s request — so a runner provisioned for one job can be “stolen” by another job with an overlapping label set. A unique id removes that overlap, so one runner serves exactly one job. For matrix jobs, make it per-job-unique, e.g. id=${{ github.run_id }}-${{ matrix.gpu }}.

Migrating from runs-on.com

The packed label is a drop-in match for runs-on.com-style syntax, and machine.dev also accepts runs-on’s spellings inside it so you can keep one-line configs you copy across. They translate to the native selectors below:

runs-on.com spellingmachine.dev selector
spot=truetenancy=spot
spot=falsetenancy=on_demand
disk=<gb> / volume=<gb>disk_size=<gb>
region=<r>regions=<r>

The native keys (gpu, cpu, ram, architecture, tenancy, regions, disk_size, disk_iops, disk_throughput, metrics, metrics_interval, id, runner) pass through unchanged.

Legacy list form. The older array syntax — runs-on: [machine, gpu=l4, tenancy=spot] — is still accepted, so existing workflows keep working untouched. It’s no longer the recommended style: the packed form above is the drop-in match for runs-on.com syntax and makes it ergonomic to thread the per-job id=${{ github.run_id }} correlation that prevents job-stealing. Prefer the packed form for new workflows.

Required selector

SelectorDescription
machineRequired, always the leading segment. Tells GitHub Actions to route the job to a machine.dev runner.

Runner type (pick one)

LabelDescription
cpu=NCPU runner. N is one of: 2, 4, 8, 16, 32, 48, 64
gpu=TYPEGPU runner. TYPE is one of: t4g, t4, l4, a10g, l40s, trainium, inferentia2

Optional labels

LabelDefaultDescription
architecturex64x64 or arm64. CPU runners support both. T4G is always ARM64.
cpu4With gpu= only. Scales vCPU: 4, 8, or 16.
ramvariesWith gpu= only. See GPU Runners.
tenancyon_demandon_demand or spot. Spot is 70–90% cheaper.
regionsautoComma-separated AWS region codes. Auto picks cheapest.
disk_size100Root volume in GB. Range: 1–16,384.
disk_iops6000Provisioned IOPS. Range: 6,000–16,000.
disk_throughput250Throughput in MB/s. Range: 250–1,000.
metricstruetrue or false. Enables instance metrics.
metrics_interval60Collection interval in seconds. Range: 1–60.

Storage: Every runner uses a gp3 EBS root volume. The default 6,000 IOPS and 250 MB/s throughput are included at no charge. Increasing above the defaults incurs prorated EBS charges — see Pricing.

Metrics: machine.dev collects metrics by default for every job and renders them as sparkline charts on the dashboard. Collected: CPU, memory, disk I/O, network, plus GPU utilization/memory/temperature/power on GPU runners.

There are no environment variables. machine.dev reads your requirements from the labels in runs-on:. Your job’s environment is determined by the runner image, not by machine.dev — use the labels themselves as your source of truth (gpu=l4, etc.).

Available regions

Region codeLocation
us-east-1US East (N. Virginia)
us-east-2US East (Ohio)
us-west-2US West (Oregon)
ca-central-1Canada (Central)
eu-south-2Europe (Spain)
ap-southeast-2Asia Pacific (Sydney)

See Regions & availability for which GPU types are available in which regions and how auto-selection works.

Examples

Minimal CPU job

jobs:
  build:
    runs-on: machine/cpu=8
    steps:
      - uses: actions/checkout@v4
      - run: make

Minimal GPU job

jobs:
  train:
    runs-on: machine/gpu=t4g   # 4 vCPU, 8 GB RAM, 16 GB VRAM, ARM64
    steps:
      - uses: actions/checkout@v4
      - run: nvidia-smi

Spot CPU build with multiple regions

runs-on: machine/cpu=32/tenancy=spot/regions=us-east-1,us-east-2,eu-south-2

Full-control GPU fine-tune with custom storage and metrics

runs-on: machine/id=${{ github.run_id }}/gpu=l40s/cpu=16/ram=128/tenancy=spot/regions=us-east-1/disk_size=500/disk_iops=10000/metrics_interval=10
#  id=<run_id>        → pins this runner to this job (no stealing)
#  disk_size=500      → bigger volume for model checkpoints
#  disk_iops=10000    → higher IOPS for fast checkpoint writes
#  metrics_interval=10 → finer-grained metrics

ARM64 CPU build

runs-on: machine/cpu=16/architecture=arm64

Next steps