Ephemeral Storage
Ephemeral storage is disk tied to the lifetime of one instance, container, or pod, erased when that instance goes away. What it means for a GitHub Actions job.
Ephemeral storage is disk space whose contents are tied to the lifetime of the compute instance that owns it, so the data is deleted when that instance stops, terminates, or is otherwise removed. Every major platform ships a version of it under a different name: instance store on a virtual machine, the writable layer on a container, an emptyDir volume on a Kubernetes pod.
For a GitHub Actions job, ephemeral storage is the disk the job actually works on. The checkout, the package manager cache, and the build output all land there, and on a machine that is discarded after the job, all three go away with it.
Definition
Ephemeral storage is storage whose durability boundary is the life of one compute unit rather than the life of the data. The boundary is set by the platform, documented per resource type, and it applies to the whole volume rather than to a particular directory on it.
Three widely used definitions line up on the same rule.
| Platform | Resource | When the data is deleted | Source |
|---|---|---|---|
| AWS EC2 | Instance store volume | Persists across a reboot, and does not persist when the instance is stopped, hibernated, or terminated | Data persistence for instance store volumes |
| Docker | Writable container layer | "Data written to the container layer doesn't persist when the container is destroyed" | Docker storage |
| Kubernetes | emptyDir volume | "When a Pod is removed from a node for any reason, the data in the emptyDir is deleted permanently" | Kubernetes volumes |
All three checked on 2026-08-13.
The AWS row carries the detail people are caught out by most often. A reboot keeps instance store data, while a stop, a hibernate, or a change of instance type does not, and AWS states that every block is cryptographically erased on stop, hibernate, or terminate. So a machine that appears to survive an operation can still come back with an empty disk.
What sits on the other side of the boundary
Durable storage keeps data after the compute goes away. Network attached block volumes (Amazon EBS, Google Persistent Disk, Azure Managed Disks) have their own lifecycle and can outlive the machine they were attached to. Object storage, container registries, and package registries are durable by design. Kubernetes draws the same line with a PersistentVolume, which has a lifecycle independent of any pod.
The practical test is a question about ownership. If deleting the compute deletes the bytes, the storage is ephemeral.
Ephemeral storage as a scheduled resource
Kubernetes goes further and treats local ephemeral storage as a resource with requests and limits. It counts the emptyDir volumes, the container writable layers, and the container logs on a node, and the kubelet evicts a pod that exceeds its ephemeral-storage limit (managing resources for containers, checked on 2026-08-13). That is a different enforcement style from CPU throttling or an out-of-memory kill, and it is why a build that fills a disk inside a pod shows up as an eviction rather than as a failed write.
Example
A repository runs its test job on a GitHub-hosted Linux runner. GitHub documents that each of these runners is a new virtual machine, and that a standard runner carries 14 GB of SSD storage (GitHub-hosted runners, checked on 2026-08-13).
name: test
on:
push:
branches: [main]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
- run: npm ci
- run: npm run build
- run: npm test
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/Follow the disk through that job. actions/checkout writes the repository into the work directory on the machine's disk. actions/cache restores the npm cache into ~/.npm on the same disk, npm ci expands node_modules there, and npm run build writes dist/ there. At the end of the job the machine is discarded, and every one of those paths goes with it. The next run of the same workflow starts on a different machine with an empty disk.
Two steps in that file exist because the disk is ephemeral. actions/cache uploads the cache to GitHub-hosted storage so a later job on a different machine can restore it, and GitHub removes entries that have not been accessed in over 7 days while holding a default limit of 10 GB per repository (dependency caching, checked on 2026-08-13). actions/upload-artifact moves dist/ off the machine for the same reason.
What survives one job
| Written during the job | Location | Survives the job |
|---|---|---|
| Checkout of the repository | Runner work directory | No |
node_modules from npm ci | Runner work directory | No |
Restored npm cache in ~/.npm | Runner home directory | No |
| Docker image layers built by the job | Local Docker storage on the runner | No |
Cache entry saved by actions/cache | GitHub-hosted cache storage | Yes, subject to the 7 day and 10 GB rules |
Artifact uploaded by actions/upload-artifact | GitHub-hosted artifact storage | Yes, for the configured retention period |
| Image pushed to a registry | Container registry | Yes |
A self-hosted runner changes the answer only when its machine outlives the job. A long lived self-hosted runner keeps its disk between jobs, which is where a stale node_modules directory or a half written file from a cancelled run comes from. A runner registered with --ephemeral takes one job and then goes away with its machine, which puts the disk back on the ephemeral side of the boundary and gives every job the same starting state.
Related Terms
- Local SSD storage physically attached to an instance: the instance store device behind a
dorlssdinstance type suffix, and how its lifecycle differs from a network attached block volume. - What happens to runner disks after a GitHub Actions job: the disk lifecycle for hosted, self-hosted, and ephemeral runners once a job reports its conclusion.
- Ephemeral runners that accept one job and then deregister: the
--ephemeralregistration flag and why autoscaling controllers depend on it. - Local SSD detection and mounting on Linux runners: how local NVMe devices are detected, formatted, and mounted for the work directory.
- Runner security documentation: compute isolation, storage volumes, and secret handling for runners.
- WarpBuild pricing: per minute rates by runner type.
FAQ
What is ephemeral storage?
Ephemeral storage is disk space whose contents are bound to the lifetime of the compute that owns it. When the instance, container, or pod goes away, the data on that disk goes with it. AWS documents instance store volumes this way, Docker documents the writable container layer this way, and Kubernetes documents emptyDir volumes this way.
Is ephemeral storage the same as a temporary directory?
A temporary directory such as /tmp is a path convention inside one filesystem, and the operating system or a cleanup job decides when its contents are removed. Ephemeral storage describes the durability of the whole volume, so a file in a home directory on an ephemeral disk disappears at the same moment as a file in /tmp on that disk.
What happens to files a GitHub Actions job writes to the runner disk?
They sit in the runner work directory for the length of the job. GitHub-hosted runners give each job a new virtual machine, so anything that has to outlive the job leaves the machine first through an artifact upload, a cache upload, or a push to a registry or object store.
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.