Documentation menu
Getting started
Dashboard & analytics
- Dashboard at a glance
- Cost analysis
- Pipeline performance
- Optimization insights
- Knowledge Base
- Connect your AI agent
Managed runners
- Runners overview
- Run your first job
- The Runners page
- Custom runners (AI Scan)
- Self-healing
- Runner image & software
- Limits & concurrency
Caching
Team & notifications
Billing & plans
Help
Run your first job on a Latchkey runner
Switch a GitHub Actions job to a managed runner by changing one line of YAML, watch it get picked up, and verify it in the dashboard.
Before you start
The one-line change#
Before: GitHub-hosted
jobs:
test:
runs-on: ubuntu-latestAfter: Latchkey
jobs:
test:
runs-on: latchkey-smallYou never have to type a label from memory: every row of the Your runners table on the Runners page has a Copy CI snippet action, and each runner's detail drawer includes a Use in CI card with the label and a copyable snippet.
Both label forms route identically; use whichever your conventions prefer:
name: CI
on: [push]
jobs:
test:
runs-on: latchkey-small
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci
- run: npm testname: CI
on: [push]
jobs:
test:
runs-on: [self-hosted, latchkey-small]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- run: npm ci
- run: npm testSizes are chosen per job, not per workflow: give the heavy job more machine and keep everything else on latchkey-small. Moving up a size doubles the per-minute rate, so it pays for itself when it at least halves the job's duration; see the sizing guidance.
jobs:
heavy-build:
runs-on: latchkey-large # 8 vCPU / 32 GB for the heavy job
quick-lint:
runs-on: latchkey-small # keep cheap jobs on small
runs-on accepts expressions, so a matrix can route each leg to the size it needs: light legs stay on the small rate while only the heavy leg pays for the bigger machine.
jobs:
test:
strategy:
matrix:
include:
- suite: unit
runner: latchkey-small
- suite: integration
runner: latchkey-large
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- run: npm run test:${{ matrix.suite }}Or generate it#
Build your runs-on line
Paste this into any workflow under .github/workflows/. Everything else in the job stays unchanged.
Ship it and verify#
Commit and trigger the workflow
Push the change or trigger the workflow manually. On GitHub, the job shows as queued until a runner picks it up: seconds if a warm runner is available, about 10 seconds for a fresh runner (GitHub-hosted typically takes 30-60 seconds), with zero queue time either way.
Verify where it ran
In the GitHub run view, the job's runner name confirms a Latchkey machine took it rather than a GitHub-hosted one. Because every runner is destroyed after one job, do not expect a familiar name from run to run: a fresh machine takes each job, which is the ephemeral design working as intended.
Find the minutes
In the Latchkey dashboard, the Runners page shows the run in your fleet activity, and its minutes appear against your free tier. Over time the same numbers surface in two more places: the billing modal (free-tier progress, billable minutes, estimated cost so far) and the Cost Analysis page, which tracks Latchkey runner spend alongside your GitHub spend. Details in Runner usage and free minutes.
If the job just sits in "queued"#
A job that never gets picked up is the standard symptom for every routing problem: the repository is not monitored, managed runners are not enabled, the label has a typo, a custom runner's image is still building, or runner launches are blocked by billing. There is no explicit error in the GitHub UI in these cases. Walk through Troubleshooting: job stays queued to pin down which one it is.
Common questions#
Do my GitHub-hosted labels keep working?
Yes. ubuntu-latest and friends keep working side by side; installing Latchkey changes nothing about them. You can migrate one job at a time and leave the rest untouched for as long as you like.
Can I mix Latchkey and GitHub-hosted runners in one workflow?
Yes, freely. runs-on is decided per job, so a workflow can run its Linux jobs on latchkey-* labels while jobs that need GPU, Windows, macOS, or arm64 hosts stay on GitHub-hosted or other runners.
Do I need to change anything besides runs-on?
For most workflows, no. The runner image is designed to match or exceed GitHub-hosted runners, and actions/setup-* steps resolve from the same toolcache layout, so the rest of the job stays as it is.
What does this first run cost me?
Minutes are billed per minute, rounded up per job, at the size's rate, and every plan includes free minutes each month. Unless you have already used up your free tier, a short test run costs nothing. See Runner usage and free minutes.