Windows GitHub Actions Runners on BYOC AWS
WarpBuild BYOC runs Windows Server 2022 GitHub Actions runners as EC2 instances inside your own AWS account. Architecture, documented minimums, images, cost.
Last verified:
Overview
WarpBuild BYOC runs Windows Server 2022 x86-64 GitHub Actions runners as EC2 instances inside your own AWS account, launched per job and terminated when the job finishes. You apply a CloudFormation stack, define a Windows custom runner on top of it, and point runs-on at that runner's label; WarpBuild watches the job queue and calls the AWS API with the IAM role the stack created.
WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners. BYOC runs on AWS, GCP, and Azure, and the feature matrix marks Windows x86-64 as supported on BYOC AWS and BYOC Azure and pending on BYOC GCP, checked on 2026-08-13. The AWS BYOC page covers the stack, the IAM surface, and the Linux path; this page covers what changes when the guest is Windows.
Three things change:
- The AWS BYOC configuration guide publishes a separate set of minimum infrastructure requirements for Windows Server 2022 x86-64 runners, and they sit above the general custom runner minimums.
- A custom Windows AMI has requirements a Linux AMI does not, starting with
aria2on the system PATH and a sysprepped source instance. - WarpBuild caches are not supported for Windows based runners (cloud runners documentation, checked on 2026-08-13), so the workflow keeps
actions/cache.
Architecture
The split is the same one Linux BYOC uses. WarpBuild operates the control plane that holds the GitHub App connection, the runner configuration, and the queue watch. Your AWS account holds the data plane: a VPC with public and private subnets, a security group, an S3 bucket for the artifact cache and runner logs, and the EC2 instances and EBS volumes created per job.
Each Windows job gets a fresh instance. Nothing carries over between jobs, which is why a Windows runner definition has to be sized for a cold machine rather than for a long-lived agent that keeps a warm package cache on local disk.
Three runner behaviors read differently on Windows, and the first two push work back onto the disk configuration:
| Behavior | Linux BYOC runner | Windows BYOC runner |
|---|---|---|
| Local NVMe instance store auto-mount | Detected at boot and mounted at the work directory, RAID-0 across multiple devices | Not supported; the work directory lives on EBS |
| WarpBuild cache action | Enabled | Not supported; use actions/cache |
| Snapshot runners | Not supported on BYOC | Not supported on BYOC or on Windows |
Because the work directory sits on EBS on every Windows job, the volume settings in the runner definition are what a slow dotnet restore or a slow MSBuild link step usually traces back to.
Resource tagging is worth setting up before the first Windows runner, since it is the only way to separate Windows spend from Linux spend in AWS Cost Explorer. The stack tags every resource it creates with warpbuild-managed-by, warpbuild-github-org, warpbuild-runner-labels, warpbuild-runner-id, warpbuild-stack-id, and warpbuild-stack-name. Filtering a cost report on warpbuild-runner-labels gives per runner class spend, so a Windows label and a Linux label on the same stack report separately with no extra instrumentation.
Configuration
Bring up the stack first, following the AWS BYOC configuration guide, then create the Windows custom runner. These are the documented numbers, checked on 2026-08-13.
| Setting | General custom runner minimum | General best practice | Windows Server 2022 x86-64 on AWS |
|---|---|---|---|
| Instance size | Your instance types in priority order | Types of similar price and performance | At least 8 vCPU, m7a series recommended |
| Disk size | 100 GB | 150 GB | Follows the general guidance |
| Disk throughput | 125 MBps | 400 MBps | 500 MBps |
| Disk IOPS | 3000 | 4000 | 6000 |
The instance row catches teams sizing from the hosted catalog. Hosted Windows runners start at 4 vCPU with 16 GB, since the 2 vCPU Windows shapes were removed on June 8, 2026, and the BYOC guidance starts a step above that at 8 vCPU. List several instance types in priority order. The workflow names one label and WarpBuild picks an available type from your list, so a capacity gap in one m7a size does not park a queued Windows job.
Two more runner-level settings apply the same way they do on Linux. Require IMDSv2 forces token-authenticated metadata requests, set on the Update Runner page or at creation time. The Instance Profile ARN field attaches AWS authority to the job itself, configured per runner, so a Windows deploy runner and a Windows test runner carry different permissions under one stack. Spot instances are supported on BYOC AWS and suit short jobs that tolerate interruption; AWS bills spot capacity in your own account at its published rates.
Custom Windows AMIs
BYOC runners can boot your own AMI, and the custom VM images guide lists what a Windows image has to carry. Linux and Windows AMIs are both supported. Four notes are specific to Windows on AWS:
aria2has to be installed and reachable through the systemPATH. WarpBuild downloads job artifacts with it because the default Windows method is slow. The guide includes a PowerShell block that unpacks the release intoC:\Tools\aria2and appends that directory to the machinePathvariable.- The EC2 instance has to be sysprepped before you create the AMI from it, through the Amazon EC2Launch settings dialog or through the Packer sysprep commands the guide links.
- Jobs run under
runneradmin, the same user GitHub's Windows runners use, and WarpBuild creates the account if the image lacks it. User-scoped environment variables baked into another account will not reach the job, so move them to machine scope. - Pre-job and post-job hooks use the
WARPBUILD_ACTIONS_RUNNER_HOOK_JOB_STARTEDandWARPBUILD_ACTIONS_RUNNER_HOOK_JOB_COMPLETEDvariables, set at machine level from PowerShell rather than in a user profile.
One operational detail catches people the first time they debug an image: the stack does not open RDP port 3389 by default, so reaching a Windows instance interactively means adding an inbound rule for your own CIDR block. More image detail is on the custom AMIs page.
The workflow
A BYOC runner is addressed by its Runner ID, which is the runner name with the warp-custom- prefix. Hosted labels and BYOC labels coexist in one workflow file.
name: build
on:
push:
branches: [main]
pull_request:
jobs:
windows-build:
runs-on: warp-custom-win2022-use1-8x
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: ~\AppData\Local\NuGet\v3-cache
key: nuget-${{ hashFiles('**/packages.lock.json') }}
- run: dotnet restore
- run: dotnet build --configuration Release --no-restore
- run: dotnet test --configuration Release --no-build
linux-package:
needs: windows-build
runs-on: warp-ubuntu-latest-x64-8x
steps:
- uses: actions/checkout@v4
- run: ./scripts/package.shOperations
Price the three routes for the same 8 vCPU, 32 GB Windows job before you migrate. WarpBuild rates come from the pricing page; the GitHub rate comes from the GitHub Actions billing reference, checked on 2026-08-13.
| Route | Rate per minute | Who bills the compute |
|---|---|---|
| GitHub-hosted 8-core Windows larger runner | $0.042 | GitHub |
WarpBuild hosted warp-windows-latest-x64-8x | $0.032 | WarpBuild |
| WarpBuild BYOC on AWS | $0.002 WarpBuild fee | Your AWS account |
On the hosted route the arithmetic is (0.042 - 0.032) / 0.042 = 24 percent lower list price, GitHub list price checked on 2026-08-13. The BYOC row is a partial bill by design: add what AWS charges your account for the m7a instances, for the EBS volumes, and for data transfer. AWS bills provisioned IOPS and throughput above the gp3 baseline separately (AWS EBS pricing, checked on 2026-08-13), so the 6000 IOPS and 500 MBps the Windows guidance calls for cost more per volume than the 3000 IOPS floor a Linux runner can sit on. Model a real month of Windows minutes with your own instance mix.
Ownership of the image patch cycle moves with the image. WarpBuild patches WarpBuild-managed runner images. A custom Windows AMI is rebuilt on your schedule, which for most Windows fleets means a monthly rebuild that folds in the Patch Tuesday updates plus whatever Visual Studio workload versions your build pins. Automate the Packer build in a workflow and keep the AMI ID in the runner definition under change control.
CI observability streams OpenTelemetry system metrics from the runner agent and correlates them with GitHub Actions job logs, which is how you separate an undersized EBS volume from a slow test suite on a Windows job. Watch disk queue depth and throughput first, since that is where the documented Windows minimums bite.
SonarQube runs tens of thousands of GitHub Actions jobs per day on WarpBuild BYOC runners in its own AWS account, across Windows and Linux. That is the shape this page is written for: one stack, several custom runners, Windows and Linux labels sharing the same VPC, S3 bucket, and tagging scheme.
Sizes and rates for those hosted labels are on the Windows runners page, and the shorter platform answer is at does BYOC support Windows runners.
FAQ
What are the documented minimums for a Windows BYOC runner on AWS?
The AWS BYOC configuration guide recommends at least 8 vCPU with the m7a series, 6000 IOPS, and 500 MBps of disk throughput for Windows Server 2022 x86-64 runners, checked on 2026-08-13. The general custom runner minimum is 100 GB, 125 MBps, and 3000 IOPS, so a Windows runner cloned from a Linux definition normally needs its disk settings raised before the first job.
Does the WarpBuild cache work on Windows BYOC runners?
No. WarpBuild caches are not supported for Windows based runners, on hosted capacity and on BYOC. Use actions/cache in the workflow for NuGet packages, MSBuild output, and other Windows build state. The S3 bucket in your stack still holds runner system logs and telemetry.
What does a Windows BYOC runner cost?
$0.002 per runner minute in WarpBuild fees. AWS bills your own account for the EC2 instance, the EBS volume, and data transfer at your rates, and the higher IOPS and throughput the Windows guidance calls for are billed by AWS above the gp3 baseline.
Start with $10 in free credits
Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.