# Migrate from BuildJet, now that the runners are gone

> Migrate from BuildJet to another GitHub Actions runner: the pre-flight checklist, the runs-on diff, and what changes when the cache allowance halves.

Source: https://latchkey.dev/learn/runners/migrate-from-buildjet  
Updated: 2026-09-20

If you still need to migrate from BuildJet, the deadline is already behind you: BuildJet stopped accepting new signups on 6 February 2026 and stopped running jobs on 31 March 2026, so any workflow still carrying a `buildjet-` label has had no runner since. The move itself is small, a `runs-on` line and a cache action per job, but the two things that break quietly are the cache allowance and the ARM memory you were getting for the same price.

BuildJet published the migration itself before it went: its shutdown post maps `buildjet-2vcpu-ubuntu-2204` to `ubuntu-latest`, or to `ubuntu-24.04-arm` for ARM workloads, and says BuildJet Cache is interoperable with `actions/cache` so you can swap `buildjet/cache@v4` for `actions/cache@v6` directly. That path works and it is the cheapest to execute.

It is also the most expensive to run. GitHub-hosted lists $0.006 a minute for Linux 2-core x64, where BuildJet charged $0.004 for the same 2 vCPU with 8 GB, so taking the recommended path is a 50% rate increase on the shape most BuildJet users were on. [BuildJet alternatives](/learn/runners/buildjet-alternatives) prices every live replacement against it.

This page is the cutover rather than the shortlist: what to inventory before you touch anything, the exact diff, what actually changes in caching, and what to run first so you find out on one job instead of on all of them.

## Why every BuildJet workflow needs a destination

BuildJet was a drop-in managed runner: a GitHub App, a `runs-on` label of the form `buildjet-<vcpu>-<os>-<version>`, and jobs ran on its hardware. Its own shutdown post gives the two dates: new signups halted on 6 February 2026, jobs stopped on 31 March 2026. The pricing page is gone with it, so the figures below were read on 2026-08-20 while the service was live and are historical.

What you were buying: $0.004 a minute at 2 vCPU with 8 GB on AMD, sizes to 32 vCPU, a 20 GB weekly per-repository cache through `buildjet/cache`, a default concurrency of 64 AMD vCPUs, and ARM cards priced identically to AMD while shipping much less memory, 3 GB against 8 GB at 2 vCPU. Three of those five have no equivalent on GitHub-hosted.

## The pre-flight checklist

Run all eight of these before you change a line. Most of the work in a runner migration is finding the jobs that were quietly depending on something the label gave them.

- **Labels.** `grep -rn "runs-on:.*buildjet" .github/workflows` finds every job. Include reusable workflows and composite actions, which a grep of the top-level files alone will miss.
- **Runner sizes.** Record the vCPU count in each label. A `buildjet-8vcpu` job moved to `ubuntu-latest` drops to 2 vCPU and will take roughly four times as long on anything parallel.
- **ARM memory.** Every `buildjet-Nvcpu-ubuntu-*-arm` job was running on about 1.5 GB per vCPU. Its replacement almost certainly has 4 GB per vCPU, which is good for the job and different for your timings.
- **Secrets.** BuildJet needed none of your secrets, but a self-hosted-style runner does. Confirm nothing in the workflow reads a value that was set on the BuildJet App rather than in repository secrets.
- **Cache keys.** Find every `buildjet/cache` step and note its `key` and `restore-keys`. The keys carry over; the allowance does not.
- **Matrix.** A matrix that fanned out to 64 AMD vCPUs at once was inside BuildJet's default concurrency. Check the ceiling on wherever you are going, because GitHub-hosted is 20 to 500 concurrent jobs by plan.
- **Artifacts.** `actions/upload-artifact` and `download-artifact` are GitHub features and are unaffected, but artifact storage counts against your plan and a BuildJet-era job may have been uploading more than you remember.
- **Concurrency groups.** `concurrency:` blocks keyed on a runner label, if you have any, need the new label.

## The before and after

The diff is one line per job. Keep the old line as a comment for a week: reverting a runner change should not require remembering what the label was.

```.github/workflows/ci.yml
jobs:
  test:
    # before
    # runs-on: buildjet-4vcpu-ubuntu-2204
    # after
    runs-on: latchkey-medium          # 4 vCPU, 16 GB
    steps:
      - uses: actions/checkout@v7
      - uses: actions/cache@v6         # was: buildjet/cache@v4
        with:
          path: ~/.npm
          key: npm-${{ hashFiles('**/package-lock.json') }}
      - run: npm ci && npm test
```

## What changes in cache behavior

This is the part that does not fail loudly. `buildjet/cache` and `actions/cache` take the same inputs, so the swap compiles and the first run looks fine. What changes is the storage behind it: BuildJet gave 20 GB per repository weekly, and GitHub gives 10 GB per repository and removes entries that have not been accessed for 7 days.

If you were storing more than 10 GB, the effect is not an error. It is eviction: GitHub evicts oldest-first as you approach the limit, so the cache you rely on least gets dropped first and your slowest job quietly stops hitting. Check what you were storing before you assume the swap is neutral, and cut the paths you cache rather than discovering the ceiling through timings.

> Branch scoping is the other silent change. A GitHub cache entry is restorable from the branch that wrote it and from the default branch, so a feature branch cannot read another feature branch's cache. Pipelines that assumed a shared cache see a cold restore on every new branch.

## What to test first

Pick the job with the most minutes, not the one that looks easiest. It is the one whose timings you know, so a regression is visible on the first run, and it is the one where a size mismatch costs real money.

1. Change one job, push to a branch, and read the wall clock against the last BuildJet run of the same job.
2. Check the cache step logs for `Cache restored from key:` rather than a size. A restore that reports a smaller cache than you expect is an eviction, not a miss.
3. Re-run the same commit once. A second run that is slower than the first means the cache did not save, which usually means the path exceeded the allowance.
4. Only then change the rest, one workflow file at a time, keeping the old label in a comment.

## If you are moving to Latchkey

Latchkey is one of the replacements priced in [BuildJet alternatives](/learn/runners/buildjet-alternatives), at $0.0025 a minute for 2 vCPU with 8 GB against the $0.004 BuildJet charged, with a dependency cache that swaps in for `buildjet/cache` in one line, though Latchkey publishes no size for it where BuildJet gave 20 GB and GitHub gives 10 GB. The constraint to check first: Latchkey runners are Linux x86_64 only, so every `-arm` job you have needs somewhere else, and sizes stop at 16 vCPU against BuildJet's 32.

The label resolves to a 2 vCPU Ubuntu 24.04 runner with 7,734 MB of memory and 43 GB free, measured on a real runner on 2026-09-20 in job `cli-02917f33-a216-4255-9f21-7043ddccad19`; the full output is quoted in [migrate from self-hosted runners](/learn/runners/migrate-from-self-hosted-runners). Compare that against the `buildjet-2vcpu` shape you were on before you move a job with a memory ceiling. The transient failures the runner repairs are the ones you were paying twice for on BuildJet, such as [a Docker Hub rate limit](/learn/failures/docker-hub-pull-rate-limit-in-ci) or [an out-of-memory kill](/learn/failures/exit-code-137-in-github-actions).

## FAQ

### BuildJet is shut down. Where do my jobs go now?

Anywhere that answers a `runs-on` label, which is every managed runner vendor. BuildJet's own post recommends GitHub-hosted and maps the labels for you, at $0.006 a minute against the $0.004 it charged. Ubicloud, Namespace, WarpBuild, Latchkey and Blacksmith all sell a Linux card at or below what you were paying.

### How much do GitHub Actions runners cost after leaving BuildJet?

GitHub-hosted lists $0.006 a minute for Linux 2-core x64, $0.005 for arm64, $0.010 for Windows and $0.062 for macOS, read on 2026-09-20, with every job rounded up to the whole minute. Your plan includes 2,000 to 50,000 private-repo minutes a month, and standard runners are free in public repositories.

### What happens to my cache when I leave BuildJet's 20 GB allowance?

It halves. GitHub gives 10 GB per repository and removes entries not accessed for 7 days, against BuildJet's 20 GB weekly. The failure mode is eviction rather than an error, so a repository storing more than 10 GB sees its least-used entries dropped and one job quietly stops hitting the cache.

### Which BuildJet alternative is the least work to adopt?

Any of them is one `runs-on` line per job, so the work is in the checklist rather than the vendor. Blacksmith is the closest like-for-like on AMD at the same $0.004 and adds 3,000 free minutes a month. Going back to GitHub-hosted needs no third-party connection at all, which is why BuildJet recommended it, and it costs the most per minute.

## References

- [BuildJet: we are shutting down, dates, label map and cache guidance (verified 2026-09-20)](https://buildjet.com/for-github-actions/blog/we-are-shutting-down)
- [GitHub Actions runner per-minute rates and rounding (verified 2026-09-20)](https://docs.github.com/en/billing/reference/actions-runner-pricing)
- [GitHub Actions dependency caching: limits and eviction (verified 2026-09-20)](https://docs.github.com/en/actions/reference/dependency-caching-reference)
- [GitHub Actions limits: concurrent jobs by plan (verified 2026-09-20)](https://docs.github.com/en/actions/reference/limits)
- [Latchkey pricing: runner sizes and rates (verified 2026-09-20)](https://latchkey.dev/pricing)

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
