Your build minutes usage is high?
Build minutes are charged by how long each step runs multiplied by the step size configured.
Which means the quickest saving available to most teams does not involve making anything faster. It involves turning down steps that were sized generously once and never revisited.
Until fairly recently that was mostly guesswork. Step metrics and the pipelines usage tabs make it measurable, so this is a good moment to go back and check.
How Pipelines costs work:
billed minutes = step duration × step size
The multiplier is just the size number. A 2x step bills two build minutes for every minute it runs, a 4x step bills four, an 8x step bills eight.
Step size | Memory | A step that runs 10 minutes bills… |
|---|
1x
| 4 GB | 10 build minutes |
2x
| 8 GB | 20 build minutes |
4x
| 16 GB | 40 build minutes |
8x
| 32 GB | 80 build minutes |
Larger sizes (16x, 24x, 32x) exist as well — see Step options for the current list. Sizes of 4x and above require a Standard or Premium plan.
Two more things fall out of that formula, and both catch people:
- Parallel steps are billed individually. Four parallel
1x steps of five minutes each cost 20 build minutes, even though they finish in five minutes of wall clock. Fan-out buys you a faster pipeline. It never buys you a cheaper one. - Only time the pipeline is actually in progress counts. Time spent acquiring a runner is not billed.
How to decide step size:
Because size and duration multiply, sizing a step up only saves money if the step gets faster by more than the multiplier.
Move a step from 1x to 2x and it has to finish in less than half the time to break even financially. From 2x to 4x, less than a quarter.
So it helps to be clear about which thing you are buying:
- Sizing up buys time. Sometimes that is exactly the right call a 40-minute step blocking every pull request is worth paying for, sometimes time is money.
- Sizing down buys build minutes. And when a step has never come close to using its allocation, it is close to free.
Sizing down is the underrated direction, because the usual reason a step is on 4x is not measurement. It is that the step ran out of memory once, somebody bumped the size, the build went green, and nobody looked again. Sometimes the investment in optimizing the build itself is worth the effort at a certain point of scale.
Step 1: Identify where the minutes are consumed
Before touching any YAML, find out which steps are actually expensive. Intuition is unreliable here, because cost is duration × size, not whichever step feels slowest.
- Workspace total. Settings → Workspace settings → Plan details shows minutes used and remaining for the current billing period, across every repository in the workspace. Needs workspace admin.
- Per repository and per build. Workspace settings → Pipelines usage breaks consumption down by repository for the current and previous billing period. This panel is available to workspace owners and admins on monthly plans.
- Per step. Open a build and hover over a step's duration. That shows the build minutes the step consumed.
We currently store the billing history for the last two months, we’re aiming to extend this visibility soon as data accrues.
Step 2: Review the Metrics tab
Open the steps using the largest size and choose the Metrics tab. You get CPU and memory usage across the life of the step, for the build container and for any service containers on it, sampled every 5 seconds. You can toggle individual services on and off to cut the noise, and hovering a point gives you the exact timestamp and value.
Three things to know before you lean on it (Step metrics):
- Metrics appear once the step has finished.
- They are retained for 14 days after the build completes. If you want a before-and-after comparison, write the numbers down.
- They are not available for steps running on self-hosted runners.
Step 3: Change one thing, then verify
Rightsizing is easy to get optimistically wrong, so treat it as a loop rather than a one-off edit:
- Note the step's current billed minutes by hovering its duration.
- Change the size on that step only not the global default.
- Run it a few times, including once on a cold cache.
- Compare billed minutes, and check the Metrics tab again to confirm you left headroom.
- If your build is using more excessive resources than you believe it should, optimising the build itself is often the next step.
Setting size per step keeps one change from affecting everything else:
pipelines:
default:
- step:
name: Unit tests
size: 1x # was 4x; measured peak memory 1.8 GB
script:
- ./run-tests.sh
- step:
name: Integration tests
size: 4x # genuinely needs it: services plus JVM heap
services:
- postgres
script:
- ./run-integration.sh
Things to keep in mind
- Step memory is shared with service containers. The step's total is split between the build container and any services on it. The build container is never given less than 1024 MB, so on a
1x step there is at most around 3 GB left for services. A memory ceiling in the graphs may be a service container's problem rather than your script's. See Databases and service containers. - The Docker service does not scale with step size. Raising a step to
2x or 4x does not give the Docker service more memory — it keeps its 1 GB default until you configure it explicitly. Sizing a step up to fix a Docker out-of-memory error is a reliable way to pay more and fix nothing. - A global
options: size: applies to every step. It is an easy way to quietly quadruple the cost of ten cheap steps because one of them needed room.
Once sizing is right
Rightsizing comes first because it requires no restructuring, you are changing one word in a YAML file. After that, the levers that genuinely reduce minutes:
- Caches for dependency downloads, prevent your steps downloading the same files each time wasting minutes.
max-time on steps that can hang, so a stuck build stops burning minutes well before the platform limit.- Being deliberate about parallelism. It is a latency tool. It costs the same minutes or slightly more.
A quick win:
- Open Workspace settings → Pipelines usage and find your most expensive repository.
- Open its recent builds and hover step durations to find the top three steps by billed minutes.
- Open the Metrics tab on each and match it against one of the four shapes above.
- Drop the size on the clearly over-provisioned ones. Leave everything else.
- Re-measure next week.
Most teams find at least one step that has been two or three sizes too big for a year. It costs one line to fix.