Skip to content
Latchkey LogoLatchkey home

Depot vs Blacksmith Docker cache for GitHub Actions builds

The depot vs blacksmith docker cache question is really one about geography: Depot keeps your layers on a remote BuildKit builder with its own NVMe disk, and Blacksmith keeps them on a sticky disk that reattaches to the runner the job is already on. That decides the workflow edit, the cold-cache failure mode, and which line of the invoice the cache lands on.

Three Docker cache models: Depot 50 GB NVMe builder, Blacksmith sticky disk at $0.50/GB, Latchkey registry
Where each vendor keeps a Docker layer cache, and what it costs on top of runner minutes, at rates read 20 September 2026. A 50 GB cache is $25 a month on either vendor by a different route.

Depot touches Docker builds in two separate products, and it matters which one you buy. Its GitHub Actions runners carry a RAM-disk accelerator and Depot Cache; its container builds are a different service, where an ephemeral EC2 builder runs an optimized BuildKit with a persistent NVMe layer cache, 50 GB by default and up to 500 GB, and builds amd64 and arm64 natively without emulation.

Blacksmith does one thing here: it gives BuildKit a disk that survives the job. useblacksmith/setup-docker-builder@v2 mounts a sticky disk keyed by the cache-key input its v2 README requires, one key per build target, and useblacksmith/build-push-action@v2 builds against it, so the cache lives beside the runner rather than in a cache service. There is no second product to buy.

Every cell below was read from the vendor's own public pricing or documentation page on 20 September 2026. Where a vendor does not publish a number, the cell says "not published" instead of carrying a guess.

Depot, Blacksmith and Latchkey side by side (read 20 September 2026)

DepotBlacksmithLatchkey
Price per minute, 2 vCPU Linux x64$0.006 (2 vCPU, 8 GB RAM, 100 GB disk, 2 GB RAM disk)$0.004 (2 vCPU, 8 GB RAM, 80 GB disk)$0.0025 (2 vCPU, 8 GB RAM, 100 GB disk)
Price per minute, 4 vCPU Linux x64$0.012 (4 vCPU, 16 GB RAM, 130 GB disk, 4 GB RAM disk)$0.008 (4 vCPU, 16 GB RAM, 80 GB disk)$0.005 (4 vCPU, 16 GB RAM, 100 GB disk)
Free tierNone standalone: 2,000 runner minutes with the $20/month Developer plan, 20,000 with the $200/month Startup plan3,000 free minutes a month, printed on every runner card30-day trial, then 2,000 included minutes a month on Developer, 4,000 on Launch, 6,000 on Scale
Billing granularityPer-second usage tracking, with whole minutes billed at the end of the month and no one-minute minimumNot publishedPer minute
Runner sizes and OS2 to 64 vCPU on Linux x64 and arm64 (Graviton4); Windows Server 2022 and 2025, with no Hyper-V; macOS at 8 vCPU2 to 32 vCPU on Linux x64 and arm64; Windows Server 2025 at 2 to 32 vCPU in public beta; macOS M4 at 6 and 12 vCPU2, 4, 8 and 16 vCPU, Ubuntu 24.04 on x86_64 only. arm64, Windows and macOS are not offered
Cache: type, limit, persistenceDepot Cache, 25 GB included on Developer and 250 GB on Startup, then $0.20/GB/month; reported at up to 1,000 MiB/s; entries are not isolated by branchColocated cache intercepts actions/cache, 25 GB free per repo per week; sticky disks are ext4 volumes, 5 per job, evicted after 7 days idle, $0.50/GB/monthSize not published. latchkey-dev/cache-action@v1 swaps one line for actions/cache, keeping path, key and restore-keys; entries are isolated per organization, versioned by OS, kept 14 days; a failed restore warns rather than failing the job
Docker build accelerationA RAM disk on every runner, 2 GB at 2 vCPU rising to 32 GB at 64 vCPU, plus remote BuildKit builders as a separate product: 16 vCPU and 32 GB by default, 50 GB of NVMe layer cache expandable to 500 GBuseblacksmith/setup-docker-builder@v2 and useblacksmith/build-push-action@v2; layers sit on a sticky disk per cache key and are garbage-collected after 8 days unusedlatchkey-dev/docker-cache-action@v1, layers held in a Latchkey-managed private registry per organization
Concurrency limitsNot publishedNone imposed, per the runner docsNot published; warm-pool capacity varies by plan
Where jobs runEphemeral EC2 instances in Depot's AWS account, or in your own account on Depot Managed; remote builders run beside the runnerBlacksmith's own regions: Ashburn, Phoenix, Amsterdam and FrankfurtLatchkey's own AWS estate on m6a-class hosts, one job per runner, private network, destroyed after the job
Self-healing or retriesNot offeredNot offeredBuilt in: transient failures are diagnosed and retried inside the run
Setup change requiredChange the runs-on label; for remote builds add depot/setup-action@v1 and swap in depot/build-push-action@v1. The repository must be owned by a GitHub organizationInstall the GitHub App, change the runs-on label, then swap two actions in the Docker jobA runs-on label change. GitHub organization accounts only

The two cache models, and what each one costs you

A Docker layer cache is only useful if it is near the machine that reads it, and the two vendors solve that in opposite directions. Blacksmith moves the disk to the job: a sticky disk is an ext4 volume that reattaches to whichever runner takes the next run with the same cache key, so BuildKit sees a warm local filesystem. Depot moves the job to the disk: the build runs on a remote builder with NVMe attached, and your runner sends context and receives an image.

The consequences show up in three places. The edit: Blacksmith is two action swaps in the Docker job, Depot is a setup action plus a project id. The failure mode: a sticky disk idle for seven days is evicted and the next build is cold. And the bill, which both marketing pages skip.

DepotBlacksmithLatchkey
Where the build runsOn a remote BuildKit builder, 16 vCPU and 32 GB by defaultOn the runner, against a mounted diskOn the runner, against a registry-backed layer cache
Where layers liveNVMe on the builder, 50 GB default and up to 500 GBA sticky disk per cache key, 5 disks per jobA Latchkey-managed private registry per organization
First run after a cold startCold: the builder cache is empty for a new projectCold: Blacksmith documents that the first Docker run is uncachedCold: the registry has no layers for a new repository
EvictionNot published for Depot Cache; storage is billed past plan inclusionsBuildKit garbage collection removes layers unused for 8 days; the disk itself goes after 7 days idleNot published
What the cache costs on top of runner minutes$20/month Developer plan includes 25 GB; $0.20/GB/month after that; build minutes billed separately at $0.04/min past 500 included$0.50/GB/month of sticky disk; the 25 GB colocated actions/cache allowance is freeIncluded in the plan
Native multi-architectureamd64 and arm64 built natively on the builder, no emulationarm64 runners exist, so a matrix builds each architecture on its own runnerNot offered: x86_64 only

Speed

Not benchmarked yet; the runner benchmark report will replace this section. We have not run the same workload on these runners ourselves, and until we have, there is no number here worth quoting.

The cheap way to get a real answer is to point one slow job at each candidate for a week, because runner selection is per job and the Actions run log gives you the timings for free.

Both vendors publish a claim, and both are marketing rather than measurement. Blacksmith's documentation says "Our customers have reported 2x to 40x improvements in build times" from Docker layer caching: a reported range, not a benchmark. Depot says its runners are "up to 3x faster than a GitHub-hosted runner" and its cache gives "10x faster caching". Neither names the workload, so neither transfers to your Dockerfile.

The number you can trust is your own cache hit rate: count how many layers say CACHED in the build log on a normal pull request. If most do, a faster cache is not your bottleneck and a cheaper runner minute is worth more. If none do, read buildx failed to reserve cache first, because a cache that is not being written is not a vendor problem.

Cost: the same month, then the cache on top

Start with the runner minutes, at the workload every comparison here uses: 10,000 Linux minutes at 2 vCPU plus 2,000 macOS minutes on a private repository.

10,000 Linux minutes at 2 vCPU2,000 macOS minutesMonthly total
Depot$60 at $0.006/min$160 at $0.08/min$220 before plan fees
Blacksmith$28 after 3,000 free minutes$160 at $0.08/min$188
Latchkey$25 at $0.0025/minNot offered: $124 on GitHub-hosted$149 plus $5 to $49 a month for the plan

On runner minutes Blacksmith is a third cheaper than Depot at both published Linux sizes, $0.004 against $0.006 at 2 vCPU and $0.008 against $0.012 at 4 vCPU, and it is the only one with a standing free tier. Depot charges exactly GitHub-hosted list price and sells more machine for it. Latchkey's own plan is $5 to $49 a month on top of that compute, and its 2,000 to 6,000 included minutes are not netted off, so the figure is gross on both counts.

Now the cache, where the two land in the same place by different routes. A 50 GB layer cache on Blacksmith is 50 GB of sticky disk at $0.50 per GB per month, which is $25 a month. The same 50 GB on Depot is the $20 Developer plan, which includes 25 GB, plus 25 GB of overage at $0.20 per GB per month, which is $5: $25 a month again. The shapes differ. Blacksmith scales linearly with the disk you keep; Depot is mostly a plan fee until you pass 25 GB.

If you use Depot's remote builders and not just its runners, there is a third meter. Build minutes are tracked by the second and billed separately: the $20 Developer plan includes 500 of them, overage is $0.04 a minute, and the Large builder consumes them at 2x, Extra Large at 4x. Two hundred builds a month at three minutes each is 600 build minutes, so 100 bill at $0.04, which is $4 on top of the plan. That is cheap until a build takes twenty minutes.

Reliability

Take uptime as unmeasured: no Actions SLA appears on either vendor's pages. What both do publish is enough to predict the bad days. Blacksmith states that the first Docker run is uncached and that a sticky disk idle for seven days is evicted, so a repository that builds weekly is permanently cold. Depot Cache is shared across branches rather than isolated per branch, which is faster and less strict than GitHub's scoping.

The failure neither addresses is the build that dies mechanically halfway through: a registry timeout, a rate limit on a base image pull, a disk full of layers. Those bill the minutes they burned, fail the job, and wait for a person to press re-run, which bills again. Docker Hub pull rate limit and registry mirror cover the two that hit Docker jobs hardest.

When to choose Depot

  • You want the build off the runner. A remote builder with 16 vCPU and 32 GB means a 2 vCPU runner can drive a large build, which is the opposite of the usual "buy a bigger runner" answer.
  • You build amd64 and arm64 from one workflow and are tired of QEMU. Depot builds both natively on the builder rather than emulating one of them.
  • Your cache is large and you would rather pay for it by the gigabyte past a plan allowance than manage disks and their idle eviction.
  • Your jobs are short and numerous, because per-second tracking with no one-minute minimum removes rounding that a lower rate does not.
  • One caveat before you commit: Depot documents that its Windows runners have no Hyper-V on EC2, so Docker on Windows is unlikely to work there.

When to choose Blacksmith

  • You want the lowest runner rate of the two: $0.004 against $0.006 at 2 vCPU, with 3,000 free minutes a month on top.
  • You want the smallest possible change. Two action swaps inside the Docker job, and the build still runs where it ran before.
  • Your Docker job also does other work, such as tests against the image it just built, and you would rather keep that on one machine than split it across a runner and a builder.
  • You want the cache and the runner from one vendor, on one invoice, with no separate build-minute meter to model.
  • Note the trade you are accepting: a sticky disk is per cache key with five disks per job, so a repository that builds many distinct images needs its keys planned rather than pasted.

Switching: the exact diff

Both start with a runs-on change, and each wants two more lines in the Docker job. Blacksmith keeps the build local and swaps the builder underneath it; Depot installs the CLI and replaces the build action, after which the build leaves the runner. Runner selection is per job, so point one Docker job at each for two weeks and compare real numbers instead of vendor claims.

.github/workflows/image.yml
 jobs:
   image:
-    runs-on: ubuntu-latest
+    runs-on: blacksmith-4vcpu-ubuntu-2404
     steps:
       - uses: actions/checkout@v7
+      - uses: useblacksmith/setup-docker-builder@v2
+        with:
+          cache-key: docker/Dockerfile
-      - uses: docker/build-push-action@v7
+      - uses: useblacksmith/build-push-action@v2
         with:
           context: .

   image-on-depot:
-    runs-on: ubuntu-latest
+    runs-on: depot-ubuntu-24.04-4
     permissions:
       contents: read
       id-token: write
     steps:
       - uses: actions/checkout@v7
+      - uses: depot/setup-action@v1
-      - uses: docker/build-push-action@v7
+      - uses: depot/build-push-action@v1
         with:
+          project: your-depot-project-id
           context: .

The verdict

For most teams the honest answer is Blacksmith, because the change is smaller, the runner rate is a third lower, and a warm local disk is a good enough cache for a Dockerfile that has not been split across a dozen images. Depot is the better buy when the build itself has outgrown the runner: native multi-architecture images, a layer cache measured in hundreds of gigabytes, or a build you want executed on a 16 vCPU machine while the job that drives it stays on a cheap one. The two cache bills land in the same place at 50 GB, $25 a month either way, so cost is not the deciding axis at that size and architecture is. What neither does is notice that the build failed because a registry timed out at minute nine, repair it, and carry on, which on a Docker-heavy pipeline is the line item that grows quietest.

Frequently asked questions

How does the Blacksmith Docker cache work?
Blacksmith mounts a sticky disk, an ext4 volume keyed by an input you set on useblacksmith/setup-docker-builder@v2, and BuildKit writes its layer cache onto it. The disk reattaches to whichever runner takes the next run with that key, so the cache is local. Blacksmith documents that layers unused for 8 days are garbage-collected, the disk is evicted after 7 days idle, and the first Docker run is uncached.
How to use Docker layer caching in GitHub Actions?
On stock GitHub-hosted runners the usual route is cache-to: type=gha, which writes layers into the same 10 GB per-repository store actions/cache uses, so a large image evicts everything else. Both vendors replace that store: Blacksmith puts layers on a sticky disk, Depot on a remote builder's NVMe. Verify either by counting CACHED lines in the log, not by trusting the setup step.
How can I share a Docker layer cache across GitHub Actions jobs?
Both products share by design, and scope it differently. A Blacksmith sticky disk is shared by cache key, so two jobs passing the same key see the same layers, five disks per job. Depot Cache is shared per project and explicitly not isolated by branch. On stock GitHub-hosted runners, entries restore only from the same branch or the default branch, which is why cross-job sharing appears to work on main and not on a pull request.
Why is my Docker layer cache not being used in GitHub Actions?
The three usual causes are a cold first run, a cache key that changes every run, and a write that failed silently. Blacksmith documents the first, and a new Depot project starts with an empty builder. For the third, the GitHub cache backend returns an error buildx reports as a reservation failure, which buildx failed to reserve cache reproduces.

Related guides

References

Docker layers that survive between jobs, with no disk to size: Latchkey at $0.0025/min at 2 vCPU. Start free → 30-day trial · No credit card