test: measure image build with registry layer cache - #2012
Draft
marians wants to merge 4 commits into
Draft
Conversation
Not for merge. Points push-to-registries at the dev orb from giantswarm/architect-orb#871 and enables cache: registry, to measure the cold-vs-warm difference on the ~5m30s image build.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Not for merge
Measurement branch for giantswarm/architect-orb#871.
push-to-registrieshas been taking a flat ~5m32s here (5m31s / 5m32s / 5m34s on #2008 / #2010 / #2011 — 3 seconds of variance across three runs is the tell that nothing is cached). It is not multi-arch emulation: bothpush-to-registriesandpush-to-registries-releasepinplatforms: linux/amd64, so noRUNstep was ever emulated.The cause is that the orb had no way to persist BuildKit's layer cache. Each job gets a fresh
setup_remote_dockerVM and a freshdocker-containerbuilder, so every build re-runs the whole Dockerfile:apt-get install build-essential,pip install mkdocs-techdocs-core, and a fullyarn workspaces focus --all --productionincluding node-gyp native compiles. The--mount=type=cachedirectives inpackages/backend/Dockerfileonly ever helped local rebuilds.Changes (both test-only)
.circleci/workflows.yml: orb →giantswarm/architect@dev:buildkit-registry-cache, andcache: registryonpush-to-registries.Note this touches a generated file (
devctl gen circleci). Landing it for real needs agen.ci.imagechange in devctl —custom.ymlcan override theorbs:map, butworkflows.build.jobsis a list that theyq *+merge appends to, so it cannot add a parameter to an existing job entry.Expected
skeleton.tar.gzis written withportable: true, noMtime: true(@backstage/cli-module-build,createDistWorkspace.cjs.js:150-151), so it's byte-identical unless a workspacepackage.jsonchanges — which means the layer aboveyarn workspaces focusshould actually hit.Caveat that will remain even once this lands: a
yarn.lockorpackage.jsonchange misses that layer and re-runs the install against a cold cache mount, so dependency bumps still cost full price.Results
push-to-registriesmain, orb 9.6.0, no cache)3m29s faster — 2.7×. The prediction held:
skeleton.tar.gzbeing byte-stable means theyarn workspaces focus --all --productionlayer hits on a source-only change.The cold run beat baseline by 17s despite uploading 554 MB of cache — that's the QEMU gating in the same orb PR, since the
tonistiigi/binfmtpull it now skips cost about what the cache export added.Verified the speedup is real rather than a skipped step: the cache landed as a proper
application/vnd.oci.image.manifest.v1+json/vnd.buildkit.cacheconfig.v0artifact (24 blobs, 554 MB), and the warm run pushed a genuine image (…11-53-40.hc44a292).Remaining caveat
A
yarn.lockorpackage.jsonchange invalidates that layer and re-runs the install against a cold cache mount, so dependency bumps still cost the full ~5m30s. That's inherent — cache mounts aren't exportable, only layers.To land this for real
This branch edits the devctl-generated
.circleci/workflows.yml, so it is not mergeable as-is.custom.ymlcan override theorbs:map (it's a map), butworkflows.build.jobsis a list that theyq *+merge appends to, so it cannot addcache: registryto an existing job entry. Landing it needs agen.ci.imageoption in devctl, plus a released architect-orb containing giantswarm/architect-orb#871.Updated results (reviewed orb revision)
push-to-registriesmain, orb 9.6.0, no cache)The 5m40s run was not a regression:
node:24-trixie-slimwas republished at2026-08-05T08:39:10Z, which moves theFROMdigest and invalidates every layer beneath it.This repo should pin its base image
packages/backend/Dockerfileuses the floatingnode:24-trixie-slim. Every upstream republish (Debian security rebuilds land in-slimtags often) produces a fully cold build regardless of the cache. Pinning by digest with Renovate managing the bump would make cache hits consistent — and is worth doing for reproducibility independently of this work. Not included here, since this branch is measurement-only.Note on the release job
cache: registryis set on the branch job only, and that is now the orb's documented recommendation rather than an accident: release-tag builds are cosign-signed and carry a provenance attestation, and should not be assembled from a cache any repo sharing the push credentials can write. See the trust-model section in the orb docs.