Skip to content
Latchkey LogoLatchkey home

Migrate from Namespace runners without a cold cache

Teams that migrate from Namespace runners are almost never leaving because of the hardware, which is good, and almost always underestimate the same thing: Namespace is not only a label, it is a set of drop-in actions and a cache that behaves unlike any other cache in this market. The label change takes a minute and the cache change decides whether the migration reads as neutral or as a regression.

Cache scope before and after: one shared namespace per runner profile against per-branch restore rules
The cache behaviour that changes on the way out, and why a new feature branch starts cold afterwards. Behaviour read from both vendors documentation on 2026-09-21.

Start with what moves and what does not. The label moves: runs-on is one line and every destination has a size that matches. The workflow steps mostly move untouched, because they are ordinary steps.

Three things do not move, and each one is a real edit. The nscloud- actions have to be swapped back for the standard ones. The cache changes scope, from shared to branch-isolated, which is a behavior change with no error attached. And the remote Docker builders that were on by default stop existing, so a workflow that deleted its buildx setup has to get it back.

What a runner profile was carrying

Namespace attaches its features to a runner profile rather than to individual steps, which is why the label looks so short and the migration is longer than it looks. A job that reads runs-on: namespace-profile-default may be getting a cache volume, a git mirror, a container image cache and a remote Docker builder without any of those appearing in the workflow file.

The undo list below is therefore a list of things to look for in the profile as well as in the YAML. Work through it before you change the label, because after you change it the symptoms are all the same symptom: the job is slower and nothing failed.

Namespace surfaceWhat it didStandard replacementWhat changes
namespace-profile-* labelSelected the profile and everything attached to itA size label, for example latchkey-smallFeatures attached to the profile stop being implicit
nscloud-checkout-actionA faster checkout using a git mirroractions/checkoutClone time returns to an ordinary shallow clone
nscloud-cache-actionA cache volume, shared across branchesactions/cache with explicit keysYou now write keys, and restores obey branch scope
Remote Docker builders, on by defaultA warm BuildKit builder beside the runnerdocker/setup-buildx-action plus cache exportLayer cache is exported and imported per build
Unit-minute billingCharged at max(vCPU, RAM divided by 2) per minuteA fixed per-size rateMemory stops costing extra when cores sit idle

The cache is the migration

This is the change most likely to make a migrated pipeline slower with nothing in the log to explain it. Namespace documents that its cache action does not support manual partitioning: entries are shared across everything using that runner profile, which includes the default branch and every feature branch at once. actions/cache is the opposite by design, restorable only from the branch that wrote the entry or from the default branch.

So a workflow that never thought about cache keys was quietly getting cross-branch hits, and on the other side it will not. The fix is not exotic, it is a prefix key and a restore-keys fallback, but it has to be written before the first run rather than discovered from a timing graph a week later. Write the keys so a new branch falls back to the default branch entry, and accept that the first run on a new dependency set is cold.

.github/workflows/ci.yml
      - uses: actions/cache@v4
        with:
          path: ~/.npm
          key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            npm-${{ runner.os }}-
            npm-

Undo the nscloud actions

Two actions account for most of what a Namespace workflow looks like, and both have a plain equivalent. The checkout action used a git mirror to make cloning cheaper; actions/checkout at its default depth of one is the replacement, and on a large repository the difference is a few seconds rather than a minute. The cache action becomes actions/cache with the keys from the section above.

Grep for the prefix rather than for the two names, because the surface is wider than most people remember: entries such as a container image cache, a tool cache directory, a cache size hint and a flag that disables the remote builders all share it. Anything matching nscloud- is either an action to replace or a setting whose effect is about to disappear.

.github/workflows/ci.yml
jobs:
  test:
    # before
    # runs-on: namespace-profile-default
    # after
    runs-on: latchkey-small
    steps:
      # - uses: namespacelabs/nscloud-checkout-action@v8
      - uses: actions/checkout@v5
      # - uses: namespacelabs/nscloud-cache-action@v1
      #   with:
      #     cache: npm
      - uses: actions/cache@v4
        with:
          path: ~/.npm
          key: npm-${{ hashFiles('**/package-lock.json') }}
          restore-keys: npm-
      - run: npm ci && npm test

Docker builds lose a warm builder

Namespace runs remote Docker builders and has them on by default, which means a workflow may have deleted its docker/setup-buildx-action step because it stopped being necessary. That step has to come back, and with it the cache export and import that a warm builder made unnecessary.

Expect the first few builds to be slower than the last few on Namespace were, and expect the ordinary Docker failure modes to reappear along with them: a rate limit once every job pulls base images again rather than finding them warm, or a cache backend that refuses a reservation. If image builds are most of your minutes, price a destination that sells a real build cache rather than assuming the layer cache covers it.

What you are giving up, stated plainly

Three properties have no equivalent on a Linux-x86_64-only destination, and one of them is usually why the team chose Namespace. It publishes the widest platform range in this market: Linux AMD64 and arm64, Windows, macOS on Apple Silicon, and Linux running on Apple Silicon at a seven times multiplier. It sells the smallest machine anybody sells, 1 vCPU with 2 GB, where every fixed-size vendor floors at two cores.

It also publishes a concurrency ceiling you can plan against, 32, 64 or 160 Linux vCPUs by plan, and its Business plan allows jobs up to 24 hours where a GitHub-hosted job caps at six. If any of those is load-bearing for you, this is a partial migration at best, and the right shape is to move the plain Linux x64 jobs and leave the rest.

The pre-flight checklist

Six items. Two greps, two decisions and two things to write before the first run rather than after it.

  • Labels. Grep for runs-on:.*namespace- and list every job, including any on Windows, macOS or Apple Silicon that cannot move at all.
  • Actions. Grep for nscloud-. Every hit is either an action to swap or a profile feature whose effect is about to go away silently.
  • Cache keys. Write them, with restore-keys prefixes, before the cutover. This is the item that decides whether the migration feels neutral.
  • Cache size. Compare what you are caching against the destination allowance, 10 GB per repository on GitHub-hosted and 25 GB on Latchkey, and decide what stops being cached.
  • Docker. Grep for docker/build-push-action and check whether a buildx setup step was removed. Put it back with cache-from and cache-to before the first image build.
  • Concurrency. Namespace publishes a vCPU ceiling by plan and most destinations publish a job count instead. A wide matrix that fitted one may queue on the other.

What no run backs, and why

Nothing on this page was reproduced on a runner, and the reason is specific to it: the two behaviors that matter most, a cache shared across branches and a cache scoped to one, only differ on the second run of a second branch. A single job proves nothing, and a harness that ran the same workflow twice on two vendors would be measuring their hardware, not their cache semantics.

So the cache behavior here is quoted from the two vendors' own documentation rather than timed, and the label and action names are read from the Namespace GitHub Actions docs on 2026-09-21. The numbers you should trust least are any about how much slower your first post-migration run will be, which is why this page does not state one.

Frequently asked questions

What replaces nscloud-cache-action when I leave Namespace?
actions/cache with keys you write yourself, plus restore-keys prefixes. The behavior is not equivalent: Namespace documents that its cache is shared across everything using a runner profile and does not support manual partitioning, while actions/cache restores only from the writing branch or the default branch. Without prefix fallbacks, every new feature branch starts cold.
Why is my pipeline slower after moving off Namespace?
Three usual causes, none of which logs an error. The cache changed scope, so cross-branch hits stopped. The remote Docker builders that were on by default went away, so layer cache is exported and imported per build again. And nscloud-checkout-action was replaced by an ordinary clone, which is slower on a large repository. Check them in that order.
Can I move all of my Namespace jobs to one destination?
Only if they are all plain Linux x86_64. Namespace publishes Linux AMD64 and arm64, Windows, macOS on Apple Silicon and Linux on Apple Silicon, and most cheap managed vendors are Linux x86_64 only. It also sells a 1 vCPU with 2 GB shape that every fixed-size vendor floors above. Expect a split rather than a switch if any of those is in use.
What do I lose in job length and concurrency?
Namespace publishes a concurrency ceiling in vCPUs by plan, 32, 64 or 160 for Linux, which is a number you can plan capacity against, and its Business plan allows jobs up to 24 hours. Destinations usually publish a concurrent job count instead, and a GitHub-hosted job is capped at six hours. A wide matrix or a long job may behave differently for reasons that have nothing to do with speed.

Related guides

References

The cache is the migration, not the label. Latchkey Fast Cache keeps your existing path, key and restore-keys. Start free → 30-day trial · No credit card