From 2894831ecd67296cc351362e3287671d67cd5fc1 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Tue, 24 Mar 2026 11:00:15 +0800 Subject: [PATCH] ci: optimize Docker image loading Loading images step currently takes ~30s +- a ton of variance. Linux CI jobs are currently taking 8-20m typically. So image builds can be up to ~6% of wall time. I've been playing around with further increasing Depot runner sizes. That delivers a considerable wall time reduction (<5m builds possible). This increases the percentage overhead of any "CI taxes," like restoring caches and pulling/loading container images. This commit implements a pair of optimizations to enable the image loading step to take as little as 5s: * We parallelize the image decompression + loading using simple `&` + `wait` shell features. * We filter out images that aren't needed for the current job. The filtering isn't fully lean - we don't currently filter out images related to cross-compiling. And we still incur overhead to download images we don't load. Those optimizations will wait for another day. --- .github/workflows/linux.yml | 44 +++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 189790fd7..bea616b76 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -2,7 +2,7 @@ name: linux on: push: - branches: [main] + branches: [ main ] pull_request: concurrency: @@ -12,7 +12,7 @@ concurrency: env: FORCE_COLOR: 1 -permissions: {} +permissions: { } jobs: crate-build: @@ -248,15 +248,41 @@ jobs: - name: Load Docker Images run: | + set -euo pipefail + + # We need to keep the image-*.tar file since it is used as a + # Makefile dependency. + load() { + image="${1%.tar.zst}" + echo "decompressing ${image}.tar.zst" + zstd -d --rm "${image}.tar.zst" + docker load --input "${image}.tar" + } + + # Avoid loading images that aren't used. + case "$(uname -m)" in + aarch64) + want_suffix=linux_aarch64.tar.zst + ;; + x86_64) + want_suffix=linux_x86_64.tar.zst + ;; + *) + echo "unsupported host arch: $(uname -m)" + exit 1 + ;; + esac + for f in build/image-*.tar.zst; do - echo "decompressing $f" - zstd -d --rm ${f} - done - - for f in build/image-*.tar; do - echo "loading $f" - docker load --input $f + if [[ "$f" == *"${want_suffix}" ]]; then + load "${f}" & + else + echo "skipping ${f}" + rm "${f}" + fi done + + wait - name: Build if: ${{ ! matrix.dry-run }}