Depot CI went generally available in March 2026, and the pitch is the same one Depot has made since its container-build product launched: up to 55x faster builds, half the cost, over stock GitHub-hosted runners. That range is wide enough to be almost meaningless on its own — 2x and 55x describe very different builds. What's actually interesting isn't the headline number. It's the one architectural decision behind it: instead of fetching your Docker layer cache over the network on every build, Depot keeps it sitting on the same disk as the builder, permanently. That's the whole trick, and it's one a self-hosted git-push pipeline running on its own hardware can copy without paying a vendor for it.
Why This Is Landing Now: The AI-Accelerated Build Era
The "AI-accelerated build era" framing in Depot's own marketing isn't just a category name. GitHub processed roughly 1 billion commits in all of 2025; by early 2026 it was handling around 275 million commits in a single week, a run-rate that puts 2026 on track for something like 14 billion commits — driven overwhelmingly by AI coding agents opening pull requests and iterating on them autonomously. CI minute consumption tracked the same curve: weekly Actions usage went from roughly 500 million minutes in 2023 to 1 billion in 2025, then to about 2.1 billion minutes in a single week in early 2026.
That volume changes what a slow cache actually costs you. A 30-second cold Docker layer fetch was an annoyance when a human triggered a handful of builds a day. It's a real bottleneck when an agent fires off a build on every commit in a loop, dozens of times an hour, across dozens of parallel branches. Cache efficiency stopped being a nice-to-have the moment build frequency stopped being human-paced.
What Depot Actually Built
Depot's speed numbers come from three separate techniques stacked together, not one clever trick:
A warm standby pool. A cold cloud VM takes anywhere from 40 seconds to 5 minutes to boot. Depot instead keeps a pool of builder instances stopped rather than terminated, so a build request only has to transition a stopped instance to running — which Depot says takes 2 to 3 seconds. Instances stay warm for two minutes after a build finishes specifically to catch the next iteration in a tight edit-build-edit loop.
A cache that never leaves the building. This is the part that matters for the rest of this post. Depot originally stored build cache on AWS EBS volumes reattached to fresh instances between builds, and measured roughly 140MB/s of write throughput — slow enough to blunt the value of caching at all. They moved the cache onto Ceph, a distributed storage cluster running on fast local NVMe, and throughput went up to about 900MB/s: roughly 6x. Every project gets 50GB of persistent cache by default, expandable to 500GB, and it's namespaced per customer and project inside the shared Ceph cluster so a fresh builder instance can attach to the right cache volume and pick up exactly where the last build left off.
Native builders instead of emulation. Multi-platform images (amd64 + arm64) built through QEMU emulation can take an hour or more per architecture. Depot instead runs the build on real x86 and real ARM hardware concurrently and stitches the manifests together, which is a separate speedup from caching but stacks with it in the same headline numbers.
Depot CI, the newer general-purpose product, applies the same colocation philosophy one layer up: its runners reserve part of host memory for a RAM-disk I/O accelerator that sits between the job and the root disk, so file I/O for the entire CI job — not just the Docker layer cache — avoids a round-trip to network storage.
Put together, that's where the 2x-55x range comes from, and it's not evenly distributed across every build. A cold multi-arch build with an empty cache mostly benefits from native builders and the standby pool — real, but closer to the low end of that range. A warm, incremental single-arch rebuild with a high cache-hit ratio is where the Ceph-backed NVMe cache does almost all the work, because nearly the entire build resolves to "reattach the same disk, skip re-fetching every unchanged layer" — that's the scenario closer to 55x. The number that should stick with you isn't 55x itself; it's that the speedup tracks cache-hit ratio almost linearly, which tells you exactly where to spend effort if you're building this yourself.
Why Colocation Beats a Remote Cache
BuildKit ships with a local cache by default, and it's genuinely fast — but it lives on the same ephemeral runner as the build, so on GitHub-hosted (or any disposable) infrastructure it dies with the runner and buys you nothing across builds. To persist a cache across ephemeral runners, BuildKit supports exportable cache backends, and the two common choices both pay a tax Depot's architecture avoids entirely:
- GitHub Actions cache (
type=gha) talks to GitHub's own cache service, but it shares a 10GB-per-repository ceiling with every other cache your repo uses. Blow past it and GitHub starts evicting older entries, which quietly degrades your hit rate over time. - Registry cache (
type=registry) stores cache layers as a separate tag alongside your image, with no GitHub-imposed size ceiling — but every cache hit is now a pull from a remote registry, a network round-trip per layer, every single build.
Both are solving the same problem: the runner is ephemeral, so the cache has to live somewhere else, and "somewhere else" means a network hop to fetch it back. Depot's architecture sidesteps the tradeoff instead of picking a side of it — the builder is ephemeral (a stopped/started VM), but the cache volume is a persistent Ceph-backed disk that gets reattached to whichever builder instance picks up the next build for that project. Nothing about the cache is remote from the builder's perspective; it's a local NVMe read the moment the volume is attached. That's the entire insight: eliminate the round-trip, don't just widen the cache's size ceiling or speed up the network path to it.
Recipe: Building the Same Colocation on Your Own Fleet
None of this requires Depot specifically. A Cluster API-managed build fleet running tenant git-push builds on owned Hetzner nodes already has the one ingredient Depot pays AWS for — real, persistent local disks attached to real machines — which means the colocation trick is a configuration decision, not a product you buy:
- Run
buildkitdas a KubernetesStatefulSet, not aDeployment. ADeploymentload-balances requests across replica pods more or less arbitrarily, so the odds that the same project's next build lands on the pod that has its cache are low. AStatefulSetgives each replica a stable identity, which is the prerequisite for routing a given tenant's builds back to the same pod on purpose. - Back the BuildKit cache directory with a local-NVMe
PersistentVolumeClaim, not network-attached storage. BuildKit's cache lives at a fixed path in the container (/home/user/.local/share/buildkitin rootless mode); mount aPersistentVolumeClaimthere that's backed by the node's own NVMe rather than a network block device — the same distinction between EBS and Ceph-on-NVMe that Depot's own 6x throughput jump came from. - Route builds with
buildx --driver remote, pinned per tenant.docker buildx create --driver remote tcp://buildkitd-N.namespace.svc.cluster.local:2376lets a build client target a specificbuildkitdreplica directly. Hash each tenant/project to a fixed replica (consistent hashing, so the mapping survives a scale-up without reshuffling everyone) and that tenant's builds keep landing on the pod holding their warm cache. - Run rootless, and set a garbage-collection policy. Rootless
buildkitdavoids needingsecurityContext.privilegedon a multi-tenant node, which matters more on a self-hosted fleet than it does inside Depot's single-tenant-per-build-instance model. Configure BuildKit's GC thresholds so a popular tenant's cache doesn't quietly consume the whole node's disk.
That recipe reproduces Depot's colocation win. It does not reproduce Depot's cache durability. Ceph is a distributed, replicated storage cluster — losing one of Depot's underlying machines doesn't lose the cache. A single PersistentVolumeClaim pinned to one node's local NVMe is a single point of failure: if that node dies, that tenant's cache is gone and their next build starts cold. That's a real, unhedged tradeoff, not a footnote — replicating the cache across nodes is exactly the distributed-storage problem Depot is paying to have solved for them, and a self-hosted fleet that wants the same durability has to either run something Ceph-like itself or accept that a node failure means an occasional cold build, not a lost tenant.
The Comparison, Side by Side
| Depot (managed) | Self-hosted colocated BuildKit | GitHub Actions cache | Registry cache | |
|---|---|---|---|---|
| Cache hit latency | Local NVMe (~900MB/s) | Local NVMe (comparable, hardware-dependent) | Network fetch, 10GB repo ceiling | Network fetch, no size ceiling |
| Persistence model | Ceph-replicated, survives instance loss | Single-node PVC, lost if node dies | Evicted past 10GB, shared across repo | Persists as long as registry tag exists |
| Cost structure | Per-second billing on top of compute | Sunk into owned Hetzner hardware, no metering | Free, bounded by GitHub's ceiling | Registry storage costs, usually marginal |
| Blast radius on failure | None — Depot absorbs it | One tenant's cache, one node | Whole-repo cache eviction | None (durable as the registry) |
The honest read of that table: Depot is buying you engineering effort you'd otherwise have to spend yourself — the Ceph cluster, the standby pool, the routing logic — packaged as a per-second bill. A fleet that already owns its hardware and already runs a Cluster API control plane isn't buying anything it doesn't already have; it's one StatefulSet and one PersistentVolumeClaim away from the same cache-hit latency, minus the replication durability, at zero incremental cost per build.
What a Self-Hosted PaaS Build Pipeline Should Actually Borrow
Strip the recipe above down to the one decision that matters most for a git-push PaaS specifically: pin each tenant's build to a specific node, and keep that tenant's cache on that node's local disk. Everything else — rootless mode, GC thresholds, the StatefulSet plumbing — is standard Kubernetes hygiene. The colocation itself is the unlock, and it's one a platform running on owned bare-metal is structurally better positioned to exploit than a rented-runner vendor is, because the node isn't going anywhere between one tenant's builds the way a disposable cloud VM is. Depot has to build a distributed cache layer and sell it back to you as a feature specifically because its builders are ephemeral cloud instances. A fleet that owns its machines gets to skip that whole layer and just... leave the cache where it is.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Its build step today is intentionally manual (docker build locally, then import the image straight into the node), so the colocated-cache architecture covered here is still ahead of it on the roadmap rather than behind it — worth knowing if you're weighing the same StatefulSet-plus-local-NVMe recipe for your own git-push pipeline. Star the repo on GitHub or deploy your first app today.



