engineering
Docker layer caching is not what you think it is
Most CI Docker caching setups spend more time transferring the cache than they save by using it.
Tomás Rivera · Performance engineering · 2026-01-15 · 8 min read
The standard advice is to export your layer cache with cache-to and import it with cache-from. It works. For large images it is also frequently a net loss, and the timing data makes that obvious once you look.
The transfer is the problem
Every job exports the cache at the end and imports it at the start. For a multi-gigabyte layer cache, that round-trip can exceed the build time it was meant to save. The build step gets faster and the job gets slower.
| Approach | Transfer per job | Net effect on a 2 GB cache |
|---|---|---|
| No cache | None | Full rebuild every time |
| registry cache-from/to | Import + export | Often net negative |
| Actions cache backend | Import + export, capped at 10 GB | Frequent misses |
| Persistent remote builder | None | Only changed layers rebuild |
The fix is to stop moving it
A persistent BuildKit instance keeps the cache on its own disk, where BuildKit already wants it. Your job attaches, builds, detaches. There is no export step because there is nothing to export.
Your next build could be twice as fast, at half the price
Start free. Migrating away is the same one line, and we publish that diff too.