Source-to-deployment workflow
How to Plan Storage for Git LFS, CI Builds & Container Images
Map each byte to source history, temporary workspace, reusable cache, retained artifact, or deployable image before changing quota or hardware.
Why one build produces several storage questions
A build pipeline does not have one meaningful “project size.” A large-file object can remain in source history, be downloaded into a clean runner, coexist with an extracted dependency cache, expand into build intermediates, be archived as an artifact, and contribute changed layers to a container image. Those copies have different lifetimes, cleanup rules, quotas, and recovery value. Adding them into one total hides the action that will actually fix a failure.
Start with an inventory of storage classes. Git LFS holds large source objects and can have separate storage and bandwidth accounting. The runner workspace exists during execution and can fail before any output is uploaded. Build caches preserve inputs or intermediate work for reuse. CI artifacts preserve selected job outputs for later download. A container registry stores manifests and compressed layers, often deduplicating some blobs while delaying reclamation of unreferenced ones.
Measure one release and one representative job
Choose a normal release and a heavier plausible job. Record current LFS storage, unique binary change per release, the LFS payload of a clean checkout, and how often a clean developer or CI environment downloads it. On the runner, measure high-water usage for checkout, dependencies, restored caches, build directories, tests, packaging, and temporary copies. Measure stored artifacts after compression and images from manifests rather than comparing uncompressed directories with hosted quota reports.
Keep the measurement boundary explicit. If an 8 GB checkout already contains 20 GB of fetched LFS files, either record 28 GB once or split the ordinary checkout and LFS payload into non-overlapping entries. Do the same for a dependency archive and its extracted tree. Peak workspace needs the largest simultaneous on-disk state; long-term quota needs the stored object after upload.
Set retention from a recovery reason
Retention should answer a concrete question. A pull-request artifact may only need to survive review. A main-branch diagnostic bundle may need to cover the usual regression-discovery delay. A signed release may need durable preservation outside the ephemeral CI artifact service. A cache is not an archive: its lifetime is valuable only while keys are likely to be requested again. A registry image may need to remain while deployed, supported, or eligible for rollback.
Run the CI Artifact Retention Planner separately for classes with different policies. Then use the Build Cache Capacity & Churn Planner to ask whether cache key turnover consumes the quota before useful reuse occurs. Shortening every retention value to the same number is simple but can erase rollback evidence while keeping low-value cache entries.
Do not confuse tags with stored image copies
Container registries are content-addressed systems. Several tags can reference one digest, and images can share base layers. Conversely, deleting a tag may leave manifests or layers until the registry's cleanup and garbage-collection process reclaims them. Estimate shared and changing bytes from a representative image, verify the documented deduplication scope, and model the delay between untagging and capacity reclamation with the Container Registry Retention Planner.
Official registry behavior differs. GitLab documents namespace-level layer deduplication and distinguishes cleanup policies from removal of underlying layers. Azure documents how untagged manifests and unique layers are reclaimed under its policies. Treat those sources as examples of why current platform documentation is required, not as universal behavior for every registry.
Protect self-hosted runners from peak failure
Hosted quota can look healthy while a runner disk fails midway through dependency extraction or image assembly. Multiply a measured per-job peak by maximum real concurrency, then subtract operating-system, toolchain, daemon, image, log, and abandoned-workspace use. Keep free-space reserve because filesystems, databases, and package managers often fail badly at the last few gigabytes. The Self-hosted Runner Disk Capacity Checker reports both the allowed concurrency and minimum modeled disk.
Recent support guidance from Atlassian and GitLab ties “no space left on device” runner failures to checkout, caches, artifacts, images, logs, and working directories. Capacity planning does not replace lifecycle cleanup. Test successful, failed, canceled, and interrupted jobs because their cleanup paths can differ.
Use quotas as inputs, not embedded facts
Provider allowances, prices, billing periods, and accounting scopes change. Copy current storage and bandwidth limits from the account and documentation into the planners. Save the source URL and date. The Git LFS Storage & Bandwidth Planner deliberately accepts both quotas rather than claiming a universal included allowance. Re-run after a plan change, organization migration, new runner architecture, or vendor policy update.
A practical review sequence
- Inventory each independent storage class and its owner.
- Measure one representative release and job without double counting.
- Forecast LFS version growth and download cadence.
- Assign artifact retention from a recovery requirement.
- Measure cache key churn and effective reuse window.
- Separate shared image layers from unique changes and pending garbage collection.
- Check runner high-water workspace at maximum concurrency.
- Apply one policy change, wait through a full cycle, and compare observed usage.
Technical sources and next steps
Consult the current GitHub Git LFS billing documentation, GitHub Actions artifact documentation, GitLab container registry storage documentation, and the relevant runner platform's cleanup guidance. These links describe platform behavior; the planners remain vendor-neutral by requiring user-entered measurements.
Audit the exact equations and units in the Developer Build Storage & Retention Formulas. If the capacity plan passes but builds remain slow, benchmark I/O and network stages separately. If the runner uses SSDs under sustained write load, test the measured daily host writes in the VM & Container SSD Endurance Planner.