Migrate from BuildJet, now that the runners are gone
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 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/workflowsfinds 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-8vcpujob moved toubuntu-latestdrops to 2 vCPU and will take roughly four times as long on anything parallel. - ARM memory. Every
buildjet-Nvcpu-ubuntu-*-armjob 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/cachestep and note itskeyandrestore-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-artifactanddownload-artifactare 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.
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 testWhat 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.
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.
- Change one job, push to a branch, and read the wall clock against the last BuildJet run of the same job.
- 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. - 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.
- 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, 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. 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 or an out-of-memory kill.
Frequently asked questions
BuildJet is shut down. Where do my jobs go now?
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?
What happens to my cache when I leave BuildJet's 20 GB allowance?
Which BuildJet alternative is the least work to adopt?
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.Related guides
References
- BuildJet: we are shutting down, dates, label map and cache guidance (verified 2026-09-20)
- GitHub Actions runner per-minute rates and rounding (verified 2026-09-20)
- GitHub Actions dependency caching: limits and eviction (verified 2026-09-20)
- GitHub Actions limits: concurrent jobs by plan (verified 2026-09-20)
- Latchkey pricing: runner sizes and rates (verified 2026-09-20)
- GitHub Actions documentation