18 June 2026 · 6 min
Cutting a 22-minute CI pipeline down to 8
A slow pipeline is not one problem. On this repo it was four: cold dependency installs, a serial test run, an unnecessary Docker rebuild, and lint running twice.
We measured first. Every job printed a timestamp at start and end, and we charted a week of runs before touching anything. Install was 5m20s median, tests 9m, image build 6m.
Caching the package store cut installs to 40 seconds. Sharding tests across four runners took the test stage to 2m30s. A layer-ordered Dockerfile brought the build to 1m50s on cache hits.
The lesson is unglamorous: profile the pipeline the way you would profile an endpoint. Guessing costs more than measuring.
jobs:
test:
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- run: bun test --shard=${{ matrix.shard }}/4