Introducing Disks: files ready 10.5x faster
Introducing Disks: persistent filesystems mounted into StarSling Runners as ordinary directories. A job reads and writes its dependency store, build output, or dataset in place, and the next job finds it already there.
Mastra now merges more than 60 pull requests a day on average, and its CI installs dependencies about 15,000 times a day. Through last month, the median job waited 26.3 seconds for its files and 56 seconds for its dependencies. Thanks to Disks, files are now ready in 2.5 seconds, a 10.5x speedup, and dependencies in 11.5 seconds, a 4.9x speedup.
Mastra made the switch by merging one pull request, opened by a StarSling agent. On the same commit and the same runner class, Disks used between 17% and 50% fewer runner minutes per pull request across three of Mastra's workflows.
| Service | Mastra jobs | Cached folder size | Files ready | Dependencies ready |
|---|---|---|---|---|
GitHub actions/cache | 186,699 | 4.5 GiB | 26.3 s | 56 s |
| StarSling Disks | 164,364 | 4.5 GiB | 2.5 s | 11.5 s |
| StarSling speedup | Same folder | 10.5x | 4.9x |
Files ready is the time from starting the restore or the mount until the stored files can be read. Dependencies ready adds pnpm setup and the install. All times are medians. actions/cache jobs ran October 18 to 31, and Disks jobs ran November 2 to 12.
actions/cache stores the folder as a compressed archive in remote storage. Each job downloads the archive and extracts it before the first file is readable. A Disk is mounted as a filesystem, and its files are readable in seconds.
For a clearer side-by-side view, we also ran GitHub actions/cache and Disks against the same folder in a public benchmark, and it shows similar speedups. You can see the benchmark run and the method in starslingdev/disks.
Every disk has a name, scoped to its repository, and one published state called a generation.
- Mount. Before a job's first step, the runner mounts the repository's published disks at their paths. Each job reads one fixed generation for its whole run.
- Write. A job writes to its own private view of the disk. Many jobs can read the same generation at the same time, each with its own writes.
- Publish. When a publishing job on your default branch succeeds, StarSling publishes its writes as the next generation. Jobs that start afterward mount it.
Pull request jobs read the published generation. Publishing belongs to your default branch, one publisher at a time, so what the next job mounts is always the output of a successful job on your default branch.
File contents and filenames are encrypted at rest, with a unique key for each storage layer.
You can view the Disks docs for publish modes, paths, and disk lifetime.
A dependency store is the first use, and the one in Mastra's numbers above. The same directory semantics cover anything a later job would rebuild or download again:
- Dependency stores: the pnpm store and the Cargo registry, each with a preset that supplies the path.
- Build output: a Rust
targetdirectory, so a build starts from the last successful one. - Toolchains: compilers and SDKs that take minutes to install.
- Datasets and reference data: mounted read-only by every job that needs them.
A job can mount up to 10 disks, each up to 200 GB.
Install the StarSling GitHub App, run the job on a StarSling Runners label, and add one step before the install:
jobs:
build:
runs-on: starsling-ubuntu-26.04
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: starslingdev/disks@v0
with:
preset: pnpm-store
publish: ${{ github.ref == 'refs/heads/main' && 'on-change' || 'never' }}
- run: pnpm install --frozen-lockfileThe first run on main publishes the store. Every job after it mounts the store warm.
The job authenticates with its GitHub OIDC token. The action is open source at starslingdev/disks.
Disks cost $0.50 per GB-month of stored data, measured daily. See pricing for details.
Disks are available to every organization on StarSling Runners with billing set up. Add the step to one workflow, merge to your default branch, and the next job mounts a warm disk.
Keep reading