logo

Faster GitHub Actions

Accelerate your GitHub Actions with Namespace while saving cost.

Namespace offers performant and configurable GitHub Runners that boot in a few seconds and come with caching capabilities to speed up your GitHub workflows.

Why Namespace Runners?

Designed as a drop-in replacement for GitHub Action runners, Namespace Runners bring to the table:

1 More capacity out of the box, starting at 4 vCPU / 16GB RAM, with higher performance per core.

2 High throughput local cache volumes to speed up job executions.

3 Highly flexible configuration of instances shape and custom runners image to fit your computing needs.

4 Native AMD64 and ARM64 support for Linux runners.

5 macOS runners on Apple Silicon (M2).

6 Our pricing model is transparent, predictable, and competitive.

7 Full compatibility with GitHub Actions: You configure your workflow to use our runners using a single-line change and can continue using GitHub Actions as usual.

Getting Started

To speed up your workflows with Namespace, you need to connect Namespace with your GitHub organization and do a one-line change to your workflow definition:

1
Connect Namespace with your GitHub organization.
2
Change the runs-on field in a workflow file to runs-on: namespace-profile-default. For example:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: namespace-profile-default
name: Build Docker image
You can read about the configuration options available, including machine sizes, in our documentation.
3
Done! Your GitHub workflow will now run on Namespace.
Namespace Runners run with 4 vCPU / 16GB RAM by default. You can flexibly change their shape.

Details

Configuring a Runner

You can configure machine shape and architecture and enable caching using the Namespace UI or by specifying runner labels in the workflow file. The two ways are equivalent and mutually-exclusive. Some newer features are only available when using Runner Profiles.

Using Runner Profiles

Create a Profile

Open GitHub runner configuration page on the Namespace Dashboard and press "New Profile".

Select a name. The name will be part of the label to specify in the runs-on option in the workflow file.

Select the desired options. See below for details on the available features.

edit profile dialog

Confirm by pressing "Create Profile".

Select the Profile

Change your workflow file to mention the runner profile name: runs-on: namespace-profile-{name}.

jobs:
myjob:
runs-on: namespace-profile-arm64-large

The cache volume will be shared between all jobs running for a Git repository.

Using Runner Labels

Alternatively you can keep the entire runner configuration version-controlled within your workflow file. Specify one of the following labels to use different runner CPU architectures or machine shapes.

LabelOSArchitecturevCPUMemory
nscloudUbuntu 22.04AMD 64-bit416 GB
nscloud-ubuntu-22.04Ubuntu 22.04AMD 64-bit416 GB
nscloud-amd64Ubuntu 22.04AMD 64-bit416 GB
nscloud-ubuntu-22.04-amd64Ubuntu 22.04AMD 64-bit416 GB
nscloud-ubuntu-22.04-amd64-4x16Ubuntu 22.04AMD 64-bit416 GB
nscloud-ubuntu-20.04-amd64-4x16Ubuntu 20.04AMD 64-bit416 GB
nscloud-arm64Ubuntu 22.04ARM 64-bit416 GB
nscloud-ubuntu-22.04-arm64Ubuntu 22.04ARM 64-bit416 GB
nscloud-ubuntu-22.04-arm64-4x16Ubuntu 22.04ARM 64-bit416 GB
nscloud-ubuntu-20.04-arm64-4x16Ubuntu 20.04ARM 64-bit416 GB

Note that only one nscloud label is allowed in the runs-on field of your workflow file. Namespace will not schedule any workflow job if runs-on specifies more than one nscloud label or invalid ones.

Runner Machine Resources

Namespace supports custom machine shapes, so you can configure your runner to a bigger or smaller machine than what is provided by the table of well-known labels above. You can specify the machine shape with the label format as follows:

runs-on: nscloud-{os}-{arch}-{vcpu}x{mem}

Where:

  • {os}: is the operating system image to use. Today, only ubuntu-22.04 and ubuntu-20.04 are allowed.
  • {arch}: can either be "amd64" or "arm64".
  • {vcpu}: acceptable number vCPU are 2, 4, 8, 16, and 32.
  • {mem}: acceptable RAM values in GB are 2, 4, 8, 16, 32, and 64. For larger values, see below.

The GitHub's Runner software requires some resources from the underlying instance. Therefore, we recommend to configure the runner with at least 8GB of memory. Below that, depending on the workload, the runner might experience some flakiness.

For example, to create a 2 vCPU 8 GB ARM runner, use the following label:

runs-on: nscloud-ubuntu-22.04-arm64-2x8

Runners will only be scheduled if the machine shape is valid and your workspace has available concurrent capacity.

Users under the "Developer", "Team", "Business" or "Business+" plan can use up to 32 vCPU and 64GB of RAM. Please contact support@namespace.so if you want to use high-memory GitHub Runners (up to 512 GB).

Details

The provisioned disk size per runner automatically scales with its shape. See machine resource shapes.

Cross-invocation Caching

Namespace cache volumes can help you dramatically speed up your GitHub Actions.

Workflows can store dependencies, tools, and any data that needs to be available across invocations. Cached data is persisted and survives the runner instance, and is available to subsequent jobs.

Because Cache Volumes are not upload or downloaded inline with the run, the size of your cache data does not negatively affect the total runtime of your job. In fact, most of the time you'll see close to zero seconds added to the total runtime when Cache volumes are used.

Cache volumes are named using "tags": each job definition that relies on the same tag, will share the Cache volume contents.

An important design principle of Cache volumes is that they're .. well, caches. So they're best-effort; and even though Namespace aims to offer a close to 100% cache hit ratio, you should not depend on Cache volumes as durable storage.

A Cache volume is just an additional "mount" in Unix terms; so you can just use them by reading or writing files to them, remounting the cache directory, and more.

If a run fails, the new contents are discarded. But if it succeeds, the new contents will be "committed" and use for subsequent runs; thus allowing you to maximize incrementality and reducing total run time of your builds and tests.

To simplify the use of Cache volumes further, checkout nscloud-cache-action which provides a simple configuration model for popular frameworks, or if you just want to cache a particular set of directories or files.

Namespace uses local fast storage for cache volumes - and some magic. Cache volumes are forked on demand, ensuring that jobs can concurrently use the same caches with uncontested read-write access.

Learn more

Using a Cache Volume

If you configured a runner using the web UI and use namespace-profile-name runner label, enable caching by simply going to the runner profile and enabling cache.

runner profile cache configuration

You can also enable make the runner configure the built-in software (Git, containerd, toolchain) to use the cache volume.

Example: Caching NPM Packages

Use our nscloud-cache-action to mount the volume under the paths you want to cache.

jobs:
  tests:
    runs-on:
      - namespace-profile-node-tests
 
    steps:
      - name: Setup npm cache
        uses: namespacelabs/nscloud-cache-action@v1
        with:
          path: |
            ~/.npm
            ./node_modules
 
      - name: Install dependencies
        run: npm install
 
	    - name: NPM tests
        run: npm run test

Caching Docker Images Across Invocations

Namespace also makes it trivial to cache container image pulls (and unpacks, often the most expensive bit) across invocations.

To enable this feature, just open the runner profile configuration, add a cache volume and check Container images.

jobs:
  tests:
    runs-on:
      - namespace-profile-integration-tests
 
    steps:
      - name: Pull ubuntu image
        run: |
          time docker pull ubuntu

The second time the above example runs, the time to pull the ubuntu container image should be close to 0, as every layer was already cached by the first run.

To ensure runner stability, when you enable this feature, the minimum cache size allowed is 50 GB. If you specify lower values, our backend automatically sets the requested cache size 50 GB.

Known issues for Docker Image caching

Docker image caching relies on standard Docker APIs. However, if you are using a tool that does not fully support Docker APIs, Docker Image caching can break your workflow. Known issues are:

Caching GitHub Tools

Namespace volumes can cache GitHub tools across invocations. For example, actions/setup-go and actions/setup-python actions first look for their binaries in $RUNNER_TOOL_CACHE directory, before fetching from remote.

To make GitHub tool cache use Namespace volumes, open the runner profile configuration, add a cache volume and check Toolchain downloads.

jobs:
  tests:
    runs-on:
      - namespace-profile-go-python-tests
 
    steps:
      - uses: actions/setup-go@v5
      - uses: actions/setup-python@v4

Caching Git Repositories

With cache volumes, you can set your GitHub workflow to cache large git repositories to speed up the checkout phase.

After you enabled the Git caching (see below how), you'll need to change your workflows to call our optimized checkout action, which will make use of the cache volume to store and retrieve the git mirrors. See the namespacelabs/nscloud-checkout-action page for more details.

To enable this feature, just open the runner profile configuration, add a cache volume and check Git repository checkouts.

jobs:
  tests:
    runs-on:
      - namespace-profile-integration-tests
 
    steps:
      - uses: namespacelabs/nscloud-checkout-action@v2
        name: Checkout
        with:
          path: my-repo
      - run: |
          cd my-repo && git status

Expected Use Cases

Note that the namespacelabs/nscloud-checkout-action is optimized to speed up only specific use-cases. If you workflows do not belog to these, you might not see the expected performance improvement.

  • Very large repositores: when the workflow needs to checkout a repository with many or big files.
  • Checkout long commits history: when the workflow needs to checkout many commits (the default is only 1).

Advanced: Protect Caches from Updates

You can configure Cache Volumes to limit what git branches can perform updates to them. This configuration allows you to use the same cache as the main branch from other branches (e.g. pull requests), but not commit changes to it.

To specify which branches can update the cache volume, open the cache volume configuration, then check Show Advanced features, and finally type the branch names.

branch cache configuration

Any GitHub Actions job belonging to git branches that are not included in the allow-list, will be able to access the Cache Volumes, but their changes to the caches' content will not be persisted in the end.

Manage Cache Access per Job

This feature is Preview.

Instead of protecting your cache per branch, you can also select which jobs may write to the cache. This allows you to share a cache amongst multiple jobs while some are not allowed to update the cache contents. Any job without commit rights can still access the cache and can also change contents locally. But any edits that it makes to the cache will be ignored for future runs.

If using runner labels, you can add the label nscloud-cache-exp-do-not-commit to a job.

jobs:
  tests:
    runs-on:
        - nscloud-ubuntu-22.04-arm64-4x16-with-cache
        - nscloud-cache-tag-cache-npm
        - nscloud-cache-size-100gb
        - nscloud-cache-exp-do-not-commit
 
    steps:
      - uses: actions/setup-node@v3

Custom Runner Images

This feature is Preview.

You can today save further time by pre-installing Ubuntu packages in the Runner base image, that you would otherwise install as part of the GitHub workflow. This feature is still in preview, we are working on its reliability and user experience. Also, this feature is only available when using Runner Profiles.

To install custom Ubuntu packages:

  1. Open the GitHub Runner configuration page.
  2. Click on an existing profile or create a new one.
  3. Click the Base image field and select Custom Ubuntu 22.04 image.
  4. Type the Ubuntu packages one by one.
    runner profile base image configuration
  5. Click on "Create Profile" or "Update Profile" button.
  6. Namespace builds the custom runner image using your workspace's Remote Builder instances and show when it's ready to use
    runner profile base image configuration ready
  7. That's it! From now on, any new GitHub Job targeting this runner profile will runs on the custom image.

The custom runner image build will fail if any of the specified packages does not exist. You can search for the list of available packages from the Ubuntu website.

All Ubuntu 22.04 packages

You can always modify the list of pre-installed packages. Any update will result in a new image build.

The Runner Custom Base Image is built starting from our default runner base image. Any GitHub workflow job using a custom base image will be delayed until the base image is built successfully.

Accelerating Docker builds

Namespace Runners seamlessly integrate with Remote Builders, allowing you to speed up your GitHub Action runs further. By offloading expensive Docker builds to Remote Builders, you offload the resource needs into the Remote Builder, allowing you to run workflows with smaller (and cheaper) runner shapes.

Each GitHub Action run on Namespace comes pre-configured with Remote Builders by default.

No additional changes to your workflow file are required. Both docker build, docker/build-push-action and any docker build compatible use are supported out of the box, and are automatically offloaded.

Remote Builders rely on Docker's buildx context. Make sure that your workflow does not overwrite the buildx context, as you may inadvertently disable Namespace's configuration.

For example, calling the action docker/setup-buildx-action would overwrite our configuration. Consider removing it or use namespacelabs/nscloud-setup-buildx-action instead.

Disabling Namespace Remote Builders

If you prefer to use the runner's local Docker builder instead of Namespace Remote Builders, you have two options:

  • Disable Remote Builders: You can request that runners created for a particular workflow job do not use Remote Builders.

    • If you are using runner profiles (see below) disable Remote Builders in the UI in the runner profile advanced configuration.
    runner profile advanced block
    • If you are configuring the runners with labels pass an additional configuration label nsc-no-remote-builders, e.g.
    jobs:
    myjob:
    	runs-on: [nscloud-ubuntu-22.04-amd64-4x16-with-builders, nscloud-no-remote-builders]
Note the use of with-builders suffix; it's required in order to apply builder related configuration.
  • Revert the Docker build context to the default: Namespace configures Remote Builders as a separate buildx context. You can switch back to the default by calling docker buildx use default. E.g.

    jobs:
    build:
    	steps:
    	- name: Use default builder
    		run: docker buildx use default

Caching Docker builds (without Remote Builders)

This feature is advanced. For most users, relying on Remote Builders is the preferred option.

Your Docker builds can now benefit from cross-invocation caching, even if your workflow does not rely on Remote Builders.

With "in-runner builder" enabled, Namespace automatically configures your instance to both upload build metadata to your workspace, so it's logged and traced; and caching is configured using a previously attached cache volume.

Make sure to size your cache appropriately, to benefit from high cache hit ratio.

If using runner labels, first make sure you configure a user cache with labels and then add the following label nscloud-exp-in-runner-builder.

jobs:
  tests:
    runs-on:
        - nscloud-ubuntu-22.04-amd64-8x32-with-cache
        - nscloud-cache-tag-example
        - nscloud-cache-size-100gb
        - nscloud-exp-in-runner-builder
 
    steps:
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .

Caveats

  • Caching using "in-runner builders" is not shared with Remote Builders; each own uses their own separate cache.
  • Although multi-platform builds are supported, only builds of the same platform as the runner itself, will experience native performance.

Billing

Using in-runner builders does not lead to any additional compute usage beyond the runner's execution time itself. In order to make use of the feature, including logging and tracing, each build made with "in-runner builders" enabled counts towards the total build usage.

High-performance Artifact Storage

This feature is Preview.

Benefit from Namespace's high-performance Artifact Storage to share workflow artifacts between jobs in your workflows.

Simply replace your uses of actions/upload-artifact and actions/download-artifact with namespace-actions/upload-artifact and namespace-actions/download-artifact.

Limitations of Namespace artifacts actions:

  • Uploaded artifacts are not displayed in the GitHub Actions UI.
  • All uploaded artifacts are retained for 30 days. retention-days input is not respected.

For example:

jobs:
  upload:
    name: Demo Upload Archive
    runs-on: namespace-profile-default
    steps:
      - name: Upload Archive
        uses: namespace-actions/upload-artifact@v0
        with:
          name: test-archive
          path: ./archive
 
  download:
    needs: upload
    name: Demo Download Archive
    runs-on: namespace-profile-default
    steps:
      - name: Download Archive
        uses: namespace-actions/download-artifact@v0
        with:
          name: test-archive
          path: /tmp/destination

Access to Private Container Registry

GitHub Actions runs on Namespace are pre-configured with authentication credentials to access your workspace's private container registry.

The container registry address is available in the environment variable NSC_CONTAINER_REGISTRY.

For example, if you want to build-and-push to the private registry, you can run the following step.

 - name: Build and push
   uses: docker/build-push-action@v5
   with:
     context: .
	 push: true
	 tags: ${{ env.NSC_CONTAINER_REGISTRY }}/my-image:v1
	 platforms: linux/amd64,linux/arm64

Or in case you need to pull an image from the private registry, you can directly use the variable NSC_CONTAINER_REGISTRY in your commands, for example.

- name: Docker pull
  run: docker pull ${{ env.NSC_CONTAINER_REGISTRY }}/my-image:v1

Advanced: Privileged workflows

Namespace Runner Instances run the runner software itself in a container. This approach facilitates software packaging and enables custom base images. See how to use custom base images.

If your workflow requires deeper access to the host system, Namespace can run your workflow as privileged and in the host pid namespace. Simply enable the corresponding experiments in your runner labels, as per example below:

runs-on:
  - nscloud-ubuntu-22.04-arm64-4x16-with-features
  - nscloud-exp-features:privileged;host-pid-namespace

If your workflow requirements are not yet covered, please reach out to support@namespace.so.

What's Next?