FJAN Logo

Pay-as-You-Go Agents vs Parallel Jobs: Which Is Cheaper?

Publicatiedatum

Leestijd

12 minuten

Delen

Illustration of build servers feeding a pipeline, with a balance scale weighing a stopwatch against a stack of coins.
Profile photo of Funs Janssen

Geschreven door Funs Janssen

Software Consultant

Ik ben Funs Janssen. Ik ontwikkel software en schrijf over de beslissingen die daarbij komen kijken: architectuur, ontwikkelmethoden, AI-tools en de zakelijke impact van technische keuzes. Deze blog is een verzameling praktische aantekeningen van echte projecten: wat schaalbaar is, wat misgaat en wat in blogvriendelijke voorbeelden vaak over het hoofd wordt gezien.

It's 3 PM, someone just merged to main, and your Windows build is fourth in the queue. Again. You already pay for four Microsoft-hosted parallel jobs, and the next thing you hear is "can we just buy another one?" Then your finance team asks why the DevOps bill keeps creeping up.

On October 1, 2026, Microsoft gave you a second option. GitHub-hosted agents with pay-as-you-go pricing are now generally available in Azure Pipelines. You pay per minute, you don't buy parallel jobs, and you get bigger machines and native Apple Silicon. The announcement lists the per-minute prices. What it doesn't tell you is whether that is cheaper than what you pay today.

That's what this post is for. I'll give you the break-even numbers against a $40 parallel job, show you why cost per build matters more than cost per minute, walk through three realistic team scenarios, and finish with a rollout checklist so you can move pipelines one at a time without surprises.

What changed on October 1

Azure Pipelines now has a new agent pool called GitHub-hosted Agents. It runs on the same infrastructure, and at the same prices, as GitHub Actions runners, but you use it from your normal Azure DevOps YAML or classic build pipelines.

What is generally available, and what is still in preview

According to the Azure DevOps blog announcement, the pay-as-you-go billing model and the macOS SKUs are generally available. The Linux and Windows SKUs are still in public preview. That matters if your organization has a policy against running production pipelines on preview features: today, macOS is the safe bet, and Linux and Windows are for piloting.

A few newer image labels are also still rolling out over the coming weeks, so not every organization sees every image yet.

What stays the same

  • Your existing pipelines are untouched. Nothing moves to the new pool unless you change the pool section in a pipeline.
  • Your parallel jobs keep working. GitHub-hosted jobs are billed separately and don't consume your existing parallel job capacity.
  • No usage, no bill. Enabling the pool costs nothing until a pipeline actually runs on it.

The two billing models side by side

You can't compare the options until you see that they charge for different things. Parallel jobs charge for concurrency. Pay-as-you-go charges for minutes.

Parallel jobs: pay for concurrency

From the Azure DevOps Services pricing page:

  • Microsoft-hosted: 1 free parallel job with 1,800 minutes per month, then $40 per extra parallel job per month with unlimited minutes.
  • Self-hosted: 1 free parallel job with unlimited minutes, then $15 per extra parallel job per month.

A Microsoft-hosted Windows or Linux agent is a 2-core machine with 7 GB of RAM. A parallel job is a slot: one job at a time, as many minutes as you can fill. If your builds run all day, that's great value. If they all run at the same time in the afternoon, you queue.

GitHub-hosted agents: pay for minutes

The per-minute prices from the announcement:

  • macOS Standard: $0.062 per minute
  • macOS XLarge: $0.102 per minute
  • Linux 8-core: $0.022 per minute
  • Linux 16-core: $0.042 per minute
  • Windows 8-core: $0.042 per minute
  • Windows 16-core: $0.082 per minute

There is no free tier and no included minutes. You also don't need a parallel job, so the only limit on concurrency is the agent limit per SKU (more on that below).

The break-even math: cost per build, not per minute

Here's the first number everyone wants: how many minutes does $40 buy on each machine?

  • Linux 8-core: about 1,818 minutes (roughly 30 hours)
  • Linux 16-core: about 952 minutes
  • Windows 8-core: about 952 minutes (roughly 16 hours)
  • Windows 16-core: about 488 minutes
  • macOS Standard: about 645 minutes (roughly 11 hours)
  • macOS XLarge: about 392 minutes

A Microsoft-hosted parallel job that is busy eight hours a day, twenty working days a month, runs about 9,600 minutes. On per-minute pricing, that same workload would cost far more than $40. So if you look at the price per minute alone, pay-as-you-go looks expensive.

That comparison is misleading, though, for two reasons.

Why bigger machines change the answer

The minutes are not the same minutes. A Microsoft-hosted Linux or Windows agent has 2 cores. The smallest GitHub-hosted Linux and Windows SKUs have 8. For work that runs in parallel, like a .NET solution with many projects, a C++ build, or a test suite that runs tests in parallel, a build that takes 20 minutes on 2 cores can drop a lot on 8 cores.

So the number to compare is cost per build:

  • Cost per build = (build minutes on the new SKU) x (price per minute)

Say a Windows build takes 20 minutes on a Microsoft-hosted agent and, after you measure it, 8 minutes on Windows 8-core. That build costs 8 x $0.042, or about $0.34. Run it 300 times a month and you spend about $101.

Do not assume a speedup. Builds limited by network downloads, single-threaded steps, or slow external tests barely get faster on more cores. Measure your own pipeline before you decide anything.

Queue time is a cost too

The second thing the per-minute view misses is waiting. With four parallel jobs, the fifth build waits. With pay-as-you-go, it starts as soon as an agent is free within your SKU limit. If five developers each lose 15 minutes a day waiting for builds, that adds up to about 25 hours a month, which likely costs more than the agent bill. You don't need to put an exact euro amount on it, but do put it in front of whoever approves the budget.

Three worked examples

These are illustrative scenarios with assumed numbers, not benchmarks. Plug in your own numbers.

1. Small .NET team, Linux builds, well within the free tier. About 900 build minutes a month on the free Microsoft-hosted parallel job. Even if Linux 8-core halves the build time, 450 minutes x $0.022 is about $9.90 a month, for something that is free today. Verdict: stay. Unless the queue is hurting you, there is nothing to win.

2. Mid-size team, Windows builds that queue every afternoon. Four paid parallel jobs ($160 a month) and about 6,000 Windows build minutes a month, with long queues after lunch. Suppose measurement shows the heavy compile jobs run in 40% of the time on Windows 8-core. Moving only those jobs, say 3,000 of the 6,000 minutes, becomes 1,200 minutes x $0.042, or about $50 a month. If that lets you drop one or two parallel jobs, you pay roughly the same or less and the afternoon queue is gone. Verdict: mix. Move the heavy builds, keep the light jobs on parallel jobs.

3. iOS team that needs Xcode 27. About 1,500 macOS build minutes a month. On macOS Standard on Apple Silicon, assume builds run 30% faster: 1,050 minutes x $0.062, or about $65 a month. That's more than one $40 parallel job. But according to the GitHub-hosted agents FAQ, new macOS versions are only available in the GitHub-hosted pool, and the Xcode 27 image is rolling out there. Verdict: switch. Here, cost is not really what decides it.

When to switch, when to stay, when to mix

Good fits for GitHub-hosted agents

  • Apple Silicon and the latest macOS and Xcode. This is the clearest win, and it's the part that is already generally available.
  • Heavy builds that get faster with more cores. Large solutions, native compiles, test suites that run in parallel.
  • Bursty workloads. Release days, end-of-sprint crunches, or a monorepo that triggers many jobs at once. You pay only when you burst.

Reasons to stay on what you have

  • Steady, all-day load. A parallel job kept busy all day is very cheap per minute. Pay-as-you-go cannot beat that.
  • Private network access. GitHub-hosted agents have no private connection (ExpressRoute or VPN) to your corporate network. If your build needs an internal package feed or database that is not reachable from the internet, you need self-hosted agents or a managed DevOps pool.
  • Hardening requirements. The hosted images don't follow CIS hardening benchmarks. If your auditors require hardened build images, check this first.
  • Production pipelines on Linux or Windows while those SKUs are still in preview, if your policy forbids preview features.

The hybrid setup most teams will end up with

For most organizations, the answer is not either/or. Keep one or two parallel jobs for the light, steady work: linting, small library builds, PR validation. Send heavy compiles, macOS, and burst capacity to GitHub-hosted agents. Keep self-hosted agents for anything that needs your private network.

Setting it up without surprises

The setup is short, and the official GitHub-hosted agents documentation on Microsoft Learn covers it well. These are the points where people get caught out.

The billing switch and the 24-hour wait

You need billing set up in your organization, using an Azure subscription in the same Microsoft Entra ID tenant as your Azure DevOps organization, and permission to change billing settings. Then:

  1. Go to Organization settings, Billing.
  2. Set Enable GitHub-hosted agents to On and select Save.
  3. Wait. Provisioning can take up to 24 hours, so don't schedule your first pipeline change for the same afternoon.

The YAML change

Moving a pipeline is a change to the pool section:

1pool:
2 name: 'GitHub-hosted Agents'
3 vmImage: 'macos-26-arm64'
4
5steps:
6- script: |
7 uname -a
8 sw_vers
9 displayName: Show agent info

If you don't set a pool, the pipeline keeps using the Azure Pipelines pool, which is your parallel jobs. That default protects you: nothing moves by accident. Check the documentation for the current image labels per SKU, because some labels are still rolling out.

While you're editing pipelines anyway, it's a good moment to check for old tasks. If you haven't done it yet, my guide to finding every Node 16 task in Azure DevOps shows how to do it in one pass.

The per-SKU agent limit

During the preview, organizations are limited to 8 GitHub-hosted agents per SKU. A ninth job on the same SKU waits in the queue. For most teams that's plenty, but if you plan to move a busy monorepo, ask for a higher limit through a support case before you start, not on release day.

Keeping the bill under control

Per-minute billing means a runaway pipeline costs real money. A test that hangs until the job timeout is now a line on your invoice.

Analytics tab and Azure Cost Management

You have two places to watch usage:

  • The pool's Analytics tab. Open the GitHub-hosted Agents pool and select Analytics for usage per SKU, with a drill-down to individual pipelines. This is where you find the expensive pipeline.
  • Azure Cost Management. Filter on meter category Azure DevOps, subcategory Azure Pipelines, unit 1/Minute. This is where finance looks.

Guardrails I'd set from day one

  • Set an Azure budget with alerts on the subscription that pays for Azure DevOps. I couldn't find a spending cap in Azure DevOps itself, so a budget alert is your early warning.
  • Set realistic job timeouts (timeoutInMinutes) on every job you move. The default is 60 minutes, far longer than most builds need.
  • Cache dependencies so you don't pay per minute for package restores you've already done a hundred times.
  • Use path filters and batched CI so a README change doesn't start a 16-core Windows build.

A rollout checklist for moving pipelines one at a time

The teams that get burned are the ones that switch everything on a Friday. Move one pipeline at a time and decide based on data. This is the checklist I'd use for every pipeline:

  1. Record a baseline. Average duration, average queue time and runs per month on the current pool, taken from the last 30 days.
  2. Pick the SKU. Choose the smallest SKU that makes sense. Start with 8-core, not 16-core.
  3. Check network dependencies. Confirm the pipeline doesn't need private feeds, databases or services behind your firewall.
  4. Check compliance. Confirm no hardening or "no preview features" rule applies to this pipeline.
  5. Set guardrails. Add timeoutInMinutes, dependency caching and path filters.
  6. Run it in parallel. Use a branch or a copy of the pipeline on the new pool for a week, alongside the original.
  7. Compare cost per build. Minutes multiplied by the SKU price, compared with your share of the parallel job cost, plus the queue time you saved.
  8. Decide and document. Switch, stay or mix, and write down why, so the next person doesn't redo the analysis.
  9. Recheck parallel jobs. After moving several pipelines, see whether you can drop a parallel job.

This is exactly the kind of process that falls apart when it lives in a wiki page nobody opens. I put checklists like this on the work item itself with the Checklist Extension for Azure DevOps: one reusable "Pipeline migration" template, added to a task per pipeline, so you can see at a glance which pipelines are measured, which are moved and which are still waiting. If you already use a release checklist in Azure DevOps, this is the same idea applied to your build infrastructure.

Conclusion

GitHub-hosted agents don't replace parallel jobs. They give you a second way to buy build capacity. The key takeaways:

  • Per minute, pay-as-you-go looks expensive. $40 buys about 1,818 Linux 8-core minutes, 952 Windows 8-core minutes or 645 macOS minutes.
  • Per build, it can be cheaper, because 8 cores can finish a build much sooner than 2 cores, and nothing waits in a queue.
  • macOS and Apple Silicon are the clearest win and are already generally available. Linux and Windows are still in preview.
  • Steady load, private network access and hardening requirements are good reasons to keep parallel jobs or self-hosted agents.
  • Most teams should mix: keep parallel jobs for the light, steady work and send the heavy and bursty jobs to the new pool.

Whatever you decide, decide per pipeline, based on measured cost per build, not on a hunch. If you want to run that migration as a repeatable process instead of a one-off spreadsheet, install the free Checklist Extension from the Visual Studio Marketplace and turn the rollout checklist above into a template your whole team uses. Setting up a new organization from scratch? My lean 7-day Azure DevOps setup for small teams is a good companion.

Frequently asked questions

Reacties

Nog geen reacties. Wees de eerste om te reageren.

Plaats een reactie

Profile photo of Funs Janssen

Geschreven door Funs Janssen

Software Consultant

Ik ben Funs Janssen. Ik ontwikkel software en schrijf over de beslissingen die daarbij komen kijken: architectuur, ontwikkelmethoden, AI-tools en de zakelijke impact van technische keuzes. Deze blog is een verzameling praktische aantekeningen van echte projecten: wat schaalbaar is, wat misgaat en wat in blogvriendelijke voorbeelden vaak over het hoofd wordt gezien.

Inhoud