> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blacksmith.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Sticky Disks

> Blacksmith optionally offers Sticky Disks to speed up your workflows

## Overview

[useblacksmith/stickydisk](https://github.com/useblacksmith/stickydisk) is a GitHub Action that helps persist state written to disk across jobs.
This action can serve as a superior alternative to the Actions cache, especially when the cache artifacts are extremely large. Each sticky disk is hot-loaded into the runner and mounted at the specified path. The sticky disk is formatted as an ext4 filesystem.

<Warning>
  The `useblacksmith/stickydisk` action is currently in beta. There may be bugs and behavior may change. Please report issues on the GitHub repository.
</Warning>

## Basics

### Cache Performance Comparison

| Caching Solution     | Cache Size | Average Download Speed | Time to Access |
| -------------------- | ---------- | ---------------------- | -------------- |
| GitHub Actions Cache | 6GB        | 90 MB/s                | \~1m6s         |
| Blacksmith Cache     | 6GB        | 400 MB/s               | \~15s          |
| Sticky Disks         | 6GB        | N/A                    | 3 seconds      |

Note that Sticky Disks can use much more than 6 GB of space - these numbers are simply a performance comparison.

### Use Cases

#### NPM Package Caching

Node.js projects can have extensive dependency trees, leading to large `node_modules` directories. Sticky disks provide persistent, high-performance storage for your NPM packages.

```yml Diff Example icon="code" lines theme={"system"}
jobs:
  build:
    runs-on: blacksmith # [!code ++]
    steps:
      - uses: actions/checkout@v6
      
      - name: Setup Node.js
        uses: useblacksmith/setup-node@v5  # [!code ++]
        with:
          node-version: '18.x'
      
      - name: Mount NPM Cache
        uses: useblacksmith/stickydisk@v1  # [!code ++]
        with:
          key: ${{ github.repository }}-npm-cache
          path: ~/.npm
      
      - name: Mount node_modules
        uses: useblacksmith/stickydisk@v1  # [!code ++]
        with:
          key: ${{ github.repository }}-node-modules
          path: ./node_modules
      
      - name: Install Dependencies
        run: npm ci

      - name: Build
        run: npm run build
```

#### Bazel Build Caching

Bazel's remote cache can significantly improve build times, but uploading and downloading cached artifacts can still be a bottleneck. Using sticky disks with Blacksmith runners provides near-instant access to your Bazel caches as they are bind mounted into your runners on demand. Our [`useblacksmith/setup-bazel@v2`](https://github.com/useblacksmith/setup-bazel) action is a zero-config way to use sticky disks to store the disk, repository, and external cache.

```yml Diff Example icon="code" lines theme={"system"}
jobs:
  build:
    runs-on: blacksmith # [!code ++]
    steps:
      - uses: actions/checkout@v6
      
      - name: Setup Bazel
        uses: useblacksmith/setup-bazel@v2  # [!code ++]
        with:
          version: '6.x'
      
      - name: Build
        run: |
          bazel build //...
```

### How it works

Blacksmith stores sticky disk artifacts in a secure, highly performant Ceph cluster, running on local NVMe drives.
Our runners proxy their requests through our Storage Agents to interact with the Ceph cluster.
Each sticky disk is uniquely identified by a key.
When a GitHub Action job requests a sticky disk, the last committed snapshot will be cloned and mounted into the runner at the specified path.
Once the job completes, the sticky disk will be unmounted and committed for future invocations.
At the moment, customers can use up to 5 sticky disks in a single GitHub Action job.

### Using Sticky Disks inside a container

If your GitHub Actions job runs inside a container, you will need to ensure that the container is hydrated with certain Blacksmith specific
environment variables and is running in privileged mode. These environment variables allow the runner to coordinate with our control plane
to hotload and commit the sticky disks used in the workflow. The privileged mode is required for mounting and unmounting block devices inside
a container.

The following changes can be made to your service container config in the workflow file:

```yml Diff Example icon="code" lines theme={"system"}
   container:
      image: mcr.microsoft.com/playwright:v1.41.1
      options: --privileged  # [!code ++:7]
      env:
        VM_ID: ${{ env.VM_ID }}
        GITHUB_REPO_NAME: ${{ env.GITHUB_REPO_NAME }}
        BLACKSMITH_STICKYDISK_TOKEN: ${{ env.BLACKSMITH_STICKYDISK_TOKEN }}
        BLACKSMITH_INSTALLATION_MODEL_ID: ${{ env.BLACKSMITH_INSTALLATION_MODEL_ID }}
        BLACKSMITH_REGION: ${{ env.BLACKSMITH_REGION }}
```

If the container image does not have `sudo` installed, you will need to install it as a step inside the container. `sudo` is required for
mounting and formatting the sticky disk with proper permissions.

```yml theme={"system"}
   steps:
      - name: Install sudo
        run: |
          apk add --no-cache sudo
```

Without these steps, you will see a `401` error, an `Unauthenticated` error, or permission-related errors when attempting to mount or use the sticky disk.

## useblacksmith/stickydisk-delete

[useblacksmith/stickydisk-delete](https://github.com/useblacksmith/stickydisk-delete) allows you to delete sticky disks programmatically. It supports two deletion methods:

### Delete by Key

Delete a specific sticky disk using its key:

```yml theme={"system"}
- name: Delete sticky disk
  uses: useblacksmith/stickydisk-delete@v1
  with:
    delete-key: my-cache-disk
```

### Delete Docker Cache

Delete Docker build cache for your repository. This should be used in conjunction with `useblacksmith/setup-docker-builder@v1`, which sets up the sticky disk for Docker build caching:

```yml theme={"system"}
- name: Delete Docker cache
  uses: useblacksmith/stickydisk-delete@v1
  with:
    delete-docker-cache: true
```

### Example: Cleanup After Build

```yml theme={"system"}
name: Build with Cleanup
on: push

jobs:
  build:
    runs-on: blacksmith-4vcpu-ubuntu-2204
    steps:
      - name: Create sticky disk for dependencies
        uses: useblacksmith/stickydisk@v1
        with:
          key: deps-cache
          path: ~/.npm

      - uses: actions/checkout@v6

      - name: Install and build
        run: |
          npm ci
          npm run build

  cleanup:
    runs-on: blacksmith-4vcpu-ubuntu-2204
    needs: build
    if: always()
    steps:
      - name: Delete sticky disk
        uses: useblacksmith/stickydisk-delete@v1
        with:
          delete-key: deps-cache
```

## Pricing

Sticky disks are charged at \$0.50/GB/mo. For pricing details, please visit our [pricing page](https://www.blacksmith.sh/pricing).

## FAQ

<AccordionGroup>
  <Accordion title="What is the eviction policy?">
    Sticky disks are automatically evicted after 7 days of inactivity. The "last used" timestamp is updated each time a job mounts the sticky disk. As long as a sticky disk is used at least once within a 7-day window, it will remain available. If no jobs use a sticky disk for 7 consecutive days, it will be automatically purged.
  </Accordion>
</AccordionGroup>
