{
  "title": "Docker build benchmark on GitHub Actions: cold and warm buildx builds on Sengi and GitHub runners",
  "page": "https://sengi.run/blog/fast-docker-builds-github-actions",
  "publisher": "Sengi",
  "measured": "2026-10-27",
  "last_checked": "2026-10-27",
  "method": {
    "cold_build": "docker/build-push-action with no-cache on a new Buildx builder: no layer cache at all",
    "cache_write": "the same build again on the same builder, every layer local, exporting cache-to type=gha,mode=max",
    "warm_build": "after a one-line comment appended to one source file, a new Buildx builder (no local layers) builds with cache-from and cache-to type=gha,mode=max",
    "time": "wall time of the build step from the Actions job's step timestamps; median of the runs listed",
    "cost": "build seconds / 60 * list price per minute",
    "images": "built, not pushed (push: false)",
    "actions": [
      "actions/checkout@v7",
      "docker/setup-buildx-action@v4",
      "docker/build-push-action@v7"
    ],
    "cache_service": "on every Sengi job in the results ACTIONS_CACHE_URL pointed at Sengi's cache service on a private address, port 51123; on ubuntu-latest, GitHub's cache",
    "repository": "private repository connected to Sengi; jobs run one runner size at a time"
  },
  "projects": [
    {
      "key": "atuin",
      "name": "Atuin server",
      "repository": "atuinsh/atuin",
      "commit": "876aa50ecaee8393f57a0dbb9aafc4b43014f78d",
      "stack": "Rust",
      "dockerfile": "cargo-chef dependency layer, then cargo build --release --bin atuin-server",
      "one_line_change": "crates/atuin-server/src/lib.rs",
      "build_args": {}
    },
    {
      "key": "umami",
      "name": "Umami",
      "repository": "umami-software/umami",
      "commit": "559e3c607c23d2c72d9bd4f6481bda428255323c",
      "stack": "Node.js, Next.js",
      "dockerfile": "pnpm install layer, then pnpm build:docker (next build)",
      "one_line_change": "src/lib/constants.ts",
      "build_args": {
        "SKIP_BUILD_GEO": "1"
      }
    },
    {
      "key": "saleor",
      "name": "Saleor",
      "repository": "saleor/saleor",
      "commit": "c982006cc04c77a97def93218dedac8d715eb041",
      "stack": "Python, Django",
      "dockerfile": "uv sync of native-extension wheels, then collectstatic",
      "one_line_change": "saleor/__init__.py",
      "build_args": {}
    }
  ],
  "runners": [
    {
      "label": "sengi-standard-2-ubuntu-2404",
      "name": "Sengi 2 vCPU",
      "vcpu": 2,
      "memory_gb": 8,
      "usd_per_minute": 0.003
    },
    {
      "label": "sengi-standard-4-ubuntu-2404",
      "name": "Sengi 4 vCPU",
      "vcpu": 4,
      "memory_gb": 16,
      "usd_per_minute": 0.006
    },
    {
      "label": "sengi-standard-8-ubuntu-2404",
      "name": "Sengi 8 vCPU",
      "vcpu": 8,
      "memory_gb": 32,
      "usd_per_minute": 0.012
    },
    {
      "label": "ubuntu-latest",
      "name": "GitHub ubuntu-latest (2 vCPU)",
      "vcpu": 2,
      "memory_gb": 8,
      "usd_per_minute": 0.006,
      "note": "private repository, billed as GitHub's 2 vCPU Linux runner"
    }
  ],
  "results": [
    {
      "project": "atuin",
      "runner": "sengi-standard-2-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.003,
      "cold_s": 373,
      "cache_write_s": 110,
      "warm_s": 104,
      "cold_usd": 0.0186,
      "warm_usd": 0.0052,
      "each_run": [
        {
          "cold_s": 373.0,
          "cache_write_s": 110.0,
          "warm_s": 102.0,
          "warm_layers_cached": 10
        },
        {
          "cold_s": 500.0,
          "cache_write_s": 113.0,
          "warm_s": 131.0,
          "warm_layers_cached": 10
        },
        {
          "cold_s": 364.0,
          "cache_write_s": 100.0,
          "warm_s": 104.0,
          "warm_layers_cached": 10
        }
      ]
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-4-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.006,
      "cold_s": 217,
      "cache_write_s": 91,
      "warm_s": 64,
      "cold_usd": 0.0217,
      "warm_usd": 0.0064,
      "each_run": [
        {
          "cold_s": 217.0,
          "cache_write_s": 101.0,
          "warm_s": 64.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 194.0,
          "cache_write_s": 87.0,
          "warm_s": 63.0,
          "warm_layers_cached": 8
        },
        {
          "cold_s": 260.0,
          "cache_write_s": 91.0,
          "warm_s": 80.0,
          "warm_layers_cached": 10
        }
      ]
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-8-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.012,
      "cold_s": 116,
      "cache_write_s": 76,
      "warm_s": 50,
      "cold_usd": 0.0232,
      "warm_usd": 0.01,
      "each_run": [
        {
          "cold_s": 116.0,
          "cache_write_s": 76.0,
          "warm_s": 50.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 102.0,
          "cache_write_s": 73.0,
          "warm_s": 48.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 126.0,
          "cache_write_s": 79.0,
          "warm_s": 56.0,
          "warm_layers_cached": 9
        }
      ]
    },
    {
      "project": "atuin",
      "runner": "ubuntu-latest",
      "runs": 1,
      "usd_per_minute": 0.006,
      "cold_s": 666,
      "cache_write_s": 234,
      "warm_s": 220,
      "cold_usd": 0.0666,
      "warm_usd": 0.022,
      "each_run": [
        {
          "cold_s": 666.0,
          "cache_write_s": 234.0,
          "warm_s": 220.0,
          "warm_layers_cached": 10
        }
      ]
    },
    {
      "project": "umami",
      "runner": "sengi-standard-2-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.003,
      "cold_s": 134,
      "cache_write_s": 163,
      "warm_s": 168,
      "cold_usd": 0.0067,
      "warm_usd": 0.0084,
      "each_run": [
        {
          "cold_s": 134.0,
          "cache_write_s": 160.0,
          "warm_s": 168.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 163.0,
          "cache_write_s": 201.0,
          "warm_s": 209.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 134.0,
          "cache_write_s": 163.0,
          "warm_s": 152.0,
          "warm_layers_cached": 26
        }
      ]
    },
    {
      "project": "umami",
      "runner": "sengi-standard-4-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.006,
      "cold_s": 112,
      "cache_write_s": 176,
      "warm_s": 101,
      "cold_usd": 0.0112,
      "warm_usd": 0.0101,
      "each_run": [
        {
          "cold_s": 112.0,
          "cache_write_s": 183.0,
          "warm_s": 100.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 100.0,
          "cache_write_s": 160.0,
          "warm_s": 101.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 149.0,
          "cache_write_s": 176.0,
          "warm_s": 128.0,
          "warm_layers_cached": 26
        }
      ]
    },
    {
      "project": "umami",
      "runner": "sengi-standard-8-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.012,
      "cold_s": 75,
      "cache_write_s": 140,
      "warm_s": 98,
      "cold_usd": 0.015,
      "warm_usd": 0.0196,
      "each_run": [
        {
          "cold_s": 68.0,
          "cache_write_s": 137.0,
          "warm_s": 98.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 81.0,
          "cache_write_s": 140.0,
          "warm_s": 108.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 75.0,
          "cache_write_s": 143.0,
          "warm_s": 96.0,
          "warm_layers_cached": 26
        }
      ]
    },
    {
      "project": "umami",
      "runner": "ubuntu-latest",
      "runs": 2,
      "usd_per_minute": 0.006,
      "cold_s": 190,
      "cache_write_s": 244,
      "warm_s": 242,
      "cold_usd": 0.019,
      "warm_usd": 0.0242,
      "each_run": [
        {
          "cold_s": 185.0,
          "cache_write_s": 252.0,
          "warm_s": 243.0,
          "warm_layers_cached": 26
        },
        {
          "cold_s": 195.0,
          "cache_write_s": 236.0,
          "warm_s": 241.0,
          "warm_layers_cached": 26
        }
      ]
    },
    {
      "project": "saleor",
      "runner": "sengi-standard-2-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.003,
      "cold_s": 56,
      "cache_write_s": 77,
      "warm_s": 29,
      "cold_usd": 0.0028,
      "warm_usd": 0.0015,
      "each_run": [
        {
          "cold_s": 56.0,
          "cache_write_s": 70.0,
          "warm_s": 29.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 56.0,
          "cache_write_s": 85.0,
          "warm_s": 33.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 62.0,
          "cache_write_s": 77.0,
          "warm_s": 27.0,
          "warm_layers_cached": 9
        }
      ]
    },
    {
      "project": "saleor",
      "runner": "sengi-standard-4-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.006,
      "cold_s": 47,
      "cache_write_s": 75,
      "warm_s": 31,
      "cold_usd": 0.0047,
      "warm_usd": 0.0031,
      "each_run": [
        {
          "cold_s": 47.0,
          "cache_write_s": 75.0,
          "warm_s": 31.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 43.0,
          "cache_write_s": 66.0,
          "warm_s": 26.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 64.0,
          "cache_write_s": 85.0,
          "warm_s": 33.0,
          "warm_layers_cached": 9
        }
      ]
    },
    {
      "project": "saleor",
      "runner": "sengi-standard-8-ubuntu-2404",
      "runs": 3,
      "usd_per_minute": 0.012,
      "cold_s": 34,
      "cache_write_s": 67,
      "warm_s": 27,
      "cold_usd": 0.0068,
      "warm_usd": 0.0054,
      "each_run": [
        {
          "cold_s": 48.0,
          "cache_write_s": 69.0,
          "warm_s": 37.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 34.0,
          "cache_write_s": 67.0,
          "warm_s": 27.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 30.0,
          "cache_write_s": 56.0,
          "warm_s": 22.0,
          "warm_layers_cached": 9
        }
      ]
    },
    {
      "project": "saleor",
      "runner": "ubuntu-latest",
      "runs": 3,
      "usd_per_minute": 0.006,
      "cold_s": 80,
      "cache_write_s": 86,
      "warm_s": 39,
      "cold_usd": 0.008,
      "warm_usd": 0.0039,
      "each_run": [
        {
          "cold_s": 79.0,
          "cache_write_s": 105.0,
          "warm_s": 39.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 81.0,
          "cache_write_s": 83.0,
          "warm_s": 39.0,
          "warm_layers_cached": 9
        },
        {
          "cold_s": 80.0,
          "cache_write_s": 86.0,
          "warm_s": 39.0,
          "warm_layers_cached": 9
        }
      ]
    }
  ],
  "excluded_runs": [
    {
      "project": "saleor",
      "runner": "sengi-standard-2-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "umami",
      "runner": "sengi-standard-2-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-2-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "saleor",
      "runner": "sengi-standard-4-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-4-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "umami",
      "runner": "sengi-standard-4-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-8-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "umami",
      "runner": "sengi-standard-8-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "saleor",
      "runner": "sengi-standard-8-ubuntu-2404",
      "rep": "1",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "saleor",
      "runner": "sengi-standard-2-ubuntu-2404",
      "rep": "2",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-2-ubuntu-2404",
      "rep": "2",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "umami",
      "runner": "sengi-standard-2-ubuntu-2404",
      "rep": "2",
      "reason": "measured before a Sengi Actions cache update shipped mid-benchmark; rerun after it"
    },
    {
      "project": "atuin",
      "runner": "sengi-standard-8-ubuntu-2404",
      "rep": "2",
      "reason": "the job's layer cache went to GitHub's cache service instead of Sengi's; rerun as another rep"
    }
  ],
  "workflow": {
    "runs_on": "sengi-standard-4-ubuntu-2404",
    "cache_from": "type=gha,scope=my-app",
    "cache_to": "type=gha,scope=my-app,mode=max"
  },
  "sources": [
    "GitHub's Actions runner pricing reference, checked October 27, 2026",
    "Sengi's published runner prices"
  ]
}
