Local SSD

A local SSD is storage physically attached to the host running an instance. Why it beats network attached volumes for build scratch space, and why it is wiped.

A local SSD is a solid state drive physically attached to the host machine that runs a cloud instance, reached over the host's own bus rather than across the storage network. Two properties follow from that placement: it is faster than a network attached volume on the same machine, and everything written to it is lost when the instance stops or is deleted.

That pairing is what makes local SSD a good fit for a GitHub Actions job. A job checks out a repository, unpacks caches, writes object files and container layers, then hands back an artifact and a conclusion. Almost every byte it writes is scratch, and scratch is exactly what a disk with no durability guarantee is for.

Definition

Each cloud provider ships the same idea under a different name.

  • AWS calls it an instance store and documents it as temporary block level storage located on disks that are physically attached to the host computer (Amazon EC2 instance store, checked on 2026-08-13).
  • GCP calls it Local SSD: disks physically attached to the server that hosts the VM, whose data persists only until the instance is stopped or deleted (About Local SSD disks, checked on 2026-08-13).
  • Azure exposes local NVMe devices on storage optimized VM families such as Lsv3 (Lsv3 series, checked on 2026-08-13).

The wording differs and the two defining characteristics hold across all three. The device sits inside the machine that runs your workload, so reads and writes do not cross the network fabric that carries traffic to a network attached volume. And the capacity belongs to the instance, so there is no replication behind it, no snapshot of it, and no way to reattach it somewhere else.

Local SSD against a network attached volume

Both present as block devices to the operating system, and a mounted filesystem on one looks like a mounted filesystem on the other. The operational differences show up everywhere else.

PropertyLocal SSDNetwork attached block volume
Where the device livesOn the host running the instanceIn a storage service reached over the network
Survives an instance stop or deleteNoYes
Detach and reattach to another machineNoYes
Snapshots and backupsNoneSupported by the provider
Resize after launchNo, capacity is fixed by the shapeUsually yes
How it is selectedBy choosing an instance type that includes itAs an independent volume resource
What it suitsScratch space for one workload runState that outlives the machine

The instance type decides whether a machine has one

Local devices are part of the hardware a shape is sold with, so the selection happens at launch and nowhere else. Each provider encodes it in the machine name.

ProviderHow local storage is selectedExample shapesReference
AWSStorage optimized families built around instance store, plus a d suffix added to other familiesi3, c5d, m6id, r6idEC2 instance type names
GCPMachine types ending in -lssd bundle Local SSD with the shapec3-standard-8-lssd, c4a-standard-4-lssdAbout Local SSD disks
AzureStorage optimized VM families that carry local NVMeLsv3, Lasv3Lsv3 series

None of the three allow a local device to be added to a running machine, which is the practical constraint behind the whole term. A fleet whose builds are disk bound has to be moved onto a different shape, and the vCPU count and memory move with it. The instance type entry covers how those attributes travel together.

Reboot, stop, and the difference between them

The lifetime rules are narrower than "the data is temporary" suggests. AWS documents that instance store data survives a reboot and is lost when the instance stops, hibernates, or terminates, or when the underlying drive fails. GCP documents the same boundary for Local SSD: the data lasts until the VM is stopped or deleted.

A runner that is destroyed after each job never reaches that boundary in an interesting way, because the machine and the disk end together. The distinction matters for a long lived machine that is stopped overnight to save money and comes back with an empty device the next morning. The ephemeral storage entry covers the lifecycle rules in full.

Several devices on one machine

Larger shapes expose more than one local device rather than one bigger drive. The common treatment is to stripe them into a single RAID 0 array with a tool such as mdadm before formatting, so sequential throughput adds up across the members. RAID 0 offers no redundancy, and losing a member loses the array. For scratch space that is already discarded at the end of the job, that tradeoff costs nothing.

Example

Take a self hosted Linux runner launched on a shape with local NVMe, where the device is formatted at boot and mounted at /mnt/local, and the runner work directory is placed underneath it. Everything actions/checkout writes then lands on the attached device, because GITHUB_WORKSPACE sits inside that work directory.

The workflow below sends the rest of the job's writes to the same mount by pointing the toolchain's cache and output directories at it.

name: build
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: [self-hosted, linux, x64]
    env:
      CARGO_HOME: /mnt/local/cargo
      CARGO_TARGET_DIR: /mnt/local/target
    steps:
      - uses: actions/checkout@v4

      - name: Show where the job is writing
        run: |
          lsblk -o NAME,SIZE,MOUNTPOINT
          df -h "$GITHUB_WORKSPACE" /mnt/local

      - uses: actions/cache@v4
        with:
          path: |
            /mnt/local/cargo/registry
            /mnt/local/target
          key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}

      - run: cargo build --release --locked
      - run: cargo test --release --locked

Running that job on a machine with the mount in place puts the checkout, the dependency registry, and the compiler output on the local device. Here is where each write in the job actually lands.

Write during the jobPathDevice
Repository checkout$GITHUB_WORKSPACE under the runner work directoryLocal SSD
Dependency registry and build output/mnt/local/cargo, /mnt/local/targetLocal SSD
Cache archive unpacked by actions/cacheThe same two pathsLocal SSD
Container layers written by a docker build step/var/lib/docker on the boot disk, unless movedNetwork attached boot volume
Uploaded artifacts and the saved cache archiveSent over the network at the end of the jobRemote service

The fourth row is the one that surprises people. The Docker daemon keeps its layer store under its data root, which defaults to the boot disk, so an image build keeps writing to the network attached volume even though the workspace moved. Moving the daemon is a machine provisioning change rather than a workflow change:

{
  "data-root": "/mnt/local/docker"
}

The last row is the reason a cache service is still part of the picture. actions/cache restores an archive into those paths at the start of the job and uploads a new archive at the end, and that archive is what carries state to the next job. The local SSD holds the unpacked copy for the length of one job, while the durable copy lives in the cache service (caching dependencies, checked on 2026-08-13).

The workloads that gain the most from this arrangement are the ones dominated by file operations: a checkout of a large repository, unpacking a multi gigabyte cache archive, container layer writes, and link steps that touch thousands of object files. A workflow whose runtime is spent inside a single compiler process on a small source tree sees very little from it.

FAQ

What is a local SSD on a cloud instance?

A local SSD is a solid state device attached to the physical host that runs the instance, reached over the host bus rather than over the storage network. Cloud providers call it an instance store on AWS, Local SSD on GCP, and local NVMe on Azure VM families that carry it.

Is data on a local SSD kept when the machine stops?

No. The device belongs to the instance, so the contents are gone once the instance stops, hibernates, or terminates. AWS documents that the data survives a reboot and is lost on stop or terminate, and GCP documents that Local SSD data persists only until the VM is stopped or deleted.

How do I get a local SSD on a GitHub Actions runner?

By launching the runner on an instance type that includes one, then mounting it at the runner work directory. Local devices cannot be attached after launch, so the shape chosen for the runner set decides whether the job has one at all.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.